2009-05-04 39 views
23

Estoy usando una vista de título personalizada en mi aplicación para cada actividad. En una de las actividades, basado en los clics de botón, necesito cambiar la vista de título personalizada. Ahora esto funciona bien cada vez que realizo una llamada a setFeatureInt.Android: cambiar la vista de título personalizada en tiempo de ejecución

Pero si trato de actualizar cualquier elemento en el título personalizado (por ejemplo, cambiar el texto de un botón o una vista de texto en el título), la actualización no se lleva a cabo.

La depuración a través del código muestra que la vista de texto y las instancias de botón no son nulas y también puedo ver la barra de título personalizada. Pero el texto en la vista de texto o el botón no se actualiza. ¿Alguien más ha enfrentado este problema? ¿Cómo lo resuelvo?

Gracias.

EDITAR

Esto es lo que he intentado. No se actualiza incluso al llamar a postInvalidate.

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.text_title); 

    TextView databar = (TextView) findViewById(R.id.title_text); 
    databar.setText("Some Text"); 
    databar.postInvalidate(); 

    Button leftButton = (Button) findViewById(R.id.left_btn); 
    leftButton.setOnClickListener(mLeftListener); 
    leftButton.setText("Left Btn"); 
    leftButton.postInvalidate(); 

    Button rightBtn = (Button) findViewById(R.id.right_btn); 
    rightBtn.setOnClickListener(mRightListener); 
    rightBtn.postInvalidate(); 
+0

Consulte esta solución alternativa http://stackoverflow.com/questions/8634319/how-to-set-different-title-for-alert-dialog-when-webview-page-is-loaded/9394561#9394561 – Sameer

Respuesta

30

El problema es que el único Window aplicación (PhoneWindow) utiliza un LayoutInflater en su método setFeatureInt y crea una instancia del nuevo diseño con inflate y attachToRoot=true. En consecuencia, cuando llama al setFeatureInt, los nuevos diseños no son reemplazados sino adjuntos al contenedor de título interno y, por lo tanto, dibujados uno sobre el otro.

Puede solucionar esto utilizando el siguiente método de ayuda en lugar de setFeatureInt. El ayudante simplemente elimina todas las vistas desde el contenedor título interna antes de la nueva característica título personalizado se establece:


private void setCustomTitleFeatureInt(int value) { 
    try { 
     // retrieve value for com.android.internal.R.id.title_container(=0x1020149) 
     int titleContainerId = (Integer) Class.forName(
      "com.android.internal.R$id").getField("title_container").get(null); 

     // remove all views from titleContainer 
     ((ViewGroup) getWindow().findViewById(titleContainerId)).removeAllViews(); 

     // add new custom title view 
     getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, value); 

    } catch(Exception ex) { 
     // whatever you want to do here.. 
    } 
} 

no estoy seguro de si el comportamiento actual setFeatureInt se pretende, pero ciertamente no se documenta de una manera u otra razón por la cual me quedo con esto a los desarrolladores de Android;)

EDITAR

Como se señaló en los comentarios, la solución mencionada no es lo ideal. En lugar de confiar en la constante com.android.internal.R.id.title_container, simplemente puede ocultar el título personalizado anterior siempre que establezca uno nuevo.

Supongamos que tiene dos diseños título personalizado:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout android:id="@+id/custom_title_1" ... 

y

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout android:id="@+id/custom_title_2" ... 

y desea reemplazar custom_title_1 con custom_title_2, que podría ocultar antigua y utilizar setFeatureInt añadir este último:

findViewById(R.id.custom_title_1).setVisibility(View.GONE); 
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_2); 
+1

¿Qué pasa si alguno de estos valores (title_container, com.android.internal) en las versiones posteriores? ¿Eso no afectará la aplicación? – lostInTransit

+1

Tienes toda la razón. Aunque es poco probable que la constante com.android.internal.title_container cambie, es incorrecto confiar en ella. Esta es una solución fea en el mejor de los casos. –

+0

Gracias. Esta otra solución funciona muy bien. Pero realmente no entiendo por qué setFeatureInt debería agregar vistas una encima de la otra en lugar de reemplazarlas. Esp con vistas que son únicas, ¡como el título! – lostInTransit

0

¿Está llamando invalidate o postInvalidate para volver a dibujar la vista después de actualizar el texto? Si se trata de una vista personalizada, ¿puedes poner un punto de interrupción en el código de dibujo para asegurarte de que se llame?

Si está en el hilo de la IU, puede llamar a 'invalidar' si no lo está, debe llamar a 'postInvalidar' o la vista no se redibujará.

+0

Si ayuda, la vista se vuelve a dibujar porque veo la barra de título actualizada, pero los controles en la barra de título no cambian – lostInTransit

0

Sólo mi valor de 2c:

Al trabajar en MapActivity, al solicitar un título personalizado no se mostraba ningún título.

Por suerte, todo lo que quería hacer era establecer el texto del título de manera diferente, y pronto me di cuenta de que sólo llamar setTitle() dentro de onCreate() trabajó para mí (lo llamé después llamé setContentView())

Lo siento, pero no tengo tiempo ahora para depurar esto más y descubrir por qué lo que estaba haciendo no funcionó, y por qué cambiarlo lo hizo funcionar. Como dije, pensé que esto podría ayudar a alguien en el futuro.

13

La forma correcta de hacer esto es como sigue:

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
setContentView(R.layout.my_layout); 
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_custom_title); 
super.onCreate(savedInstanceState); 

Tenga en cuenta que el orden de estos estados es muy importante.

Si llama a super.onCreate() antes de cualquiera de las otras declaraciones, obtendrá una barra de título en blanco, que solucionará el problema de encontrar la ID de la barra de título y eliminar todas las vistas de ella, pero no se recomienda.

+0

OP está intentando cambiar la barra de título durante el tiempo de ejecución, después de onCreate(). – CACuzcatlan

Cuestiones relacionadas