Android: cambia la vista de título personalizado en tiempo de ejecución

Estoy usando una vista de título personalizada en mi aplicación para cada actividad. En una de las actividades, basándome en clics de botón, necesito cambiar la vista de título personalizado. Ahora esto funciona bien cada vez que hago una llamada a setFeatureInt.

Pero si intento 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 tiene lugar.

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(); 

El problema es que la única implementación de Window ( PhoneWindow ) utiliza un LayoutInflater en su método setFeatureInt e instancia el nuevo diseño con attachToRoot=true y attachToRoot=true . Por consiguiente, cuando llama a setFeatureInt , los nuevos diseños no se reemplazan sino que se adjuntan al contenedor de título interno y, por tanto, se dibujan uno encima del otro.

Puede solucionar esto utilizando el siguiente método auxiliar en lugar de setFeatureInt . El ayudante simplemente elimina todas las vistas del contenedor de título interno antes de que se configure la nueva función de título personalizado:

 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 si el actual setFeatureInt comportamiento está destinado, pero ciertamente no está documentado de una manera u otra que es la razón por la que voy a tomar esto a los desarrolladores de Android;)

EDITAR

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

Supongamos que tiene dos diseños de títulos personalizados:

 <?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 , podría ocultar el anterior y utilizar setFeatureInt para agregar el último:

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

La forma correcta de hacerlo es la siguiente:

 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 estas declaraciones es muy importante.

Si llama a super.onCreate () antes de cualquiera de las otras instrucciones, obtendrá una barra de título en blanco, que el hack de encontrar la ID de barra de título y la eliminación de todas las vistas de él se arreglará, pero no se recomienda.

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

Si está en el subproceso de UI, puede llamar a "invalidar" si no lo está, debe llamar a "postInvalidate" o la vista no se volverá a dibujar.

Sólo mi valor 2c:

Cuando se trabaja en MapActivity, al solicitar un título personalizado no se muestra ningún título.

Afortunadamente, 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 a setTitle () dentro de onCreate () funcionó para mí (lo llamé después de que llamé setContentView)

Lo siento, pero no tengo tiempo ahora para depurar esto y averiguar por qué lo que estaba haciendo no funcionó, y por qué cambiarlo hizo que funcione. Como he dicho, sólo pensé que esto podría ayudar a alguien en el camino.

  • SherlockActionBar: Cómo ajustar CustomView contra actionBar
  • Canvas.drawArc () artefactos
  • Establecer valor de enum en xml del recurso
  • Botones circulares Vista de grupo
  • La vista personalizada de Android vuelve a la posición original al actualizar
  • ¿Necesito los tres constructores para una vista personalizada de Android?
  • Cómo usar una misma fontface personalizada para toda la vista en android?
  • Vista avanzada de la lista personalizada
  • Android dibujar círculo con 2 colores (gráfico circular)
  • Cómo leer atributos personalizados en Android
  • Rellenar lista de vista personalizada mediante ListFragment
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.