Pregunta

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

Pero si intento actualizar algún 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 realiza.

La depuración a través del código muestra que la vista de texto y las instancias de los botones 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.

EDIT

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();
¿Fue útil?

Solución

El problema es que la única Window implementació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 a setFeatureInt , los nuevos diseños no se reemplazan sino se adjuntan al contenedor de títulos interno y, por lo tanto, se dibujan uno encima del otro.

Puede solucionar esto utilizando el siguiente método auxiliar en lugar de setFeatureInt . El asistente simplemente elimina todas las vistas del contenedor de títulos interno antes de configurar 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 de si está previsto el comportamiento actual de setFeatureInt , pero ciertamente no está documentado de una manera u otra, por lo que llevaré esto a los desarrolladores de Android;)

EDIT

Como se señaló en los comentarios, la solución antes mencionada no es la ideal. En lugar de confiar en la constante com.android.internal.R.id.title_container , simplemente podría ocultar el título personalizado anterior cada vez 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 , puede ocultar el anterior y usar 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);

Otros consejos

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 afirmaciones, obtendrá una barra de título en blanco, que se solucionará, pero no se recomienda el truco de encontrar la ID de la barra de título y eliminar todas las Vistas. p>

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

Si estás en el subproceso de la IU, puedes llamar 'invalidar' si no lo estás, debes llamar 'postInvalidate' o la vista no se volverá a dibujar.

Sólo mi valor 2c:

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

Afortunadamente, todo lo que quería hacer era configurar el texto del título de manera diferente, y pronto me di cuenta de que solo llamar a setTitle () dentro de onCreate () funcionaba para mí (lo llamé después de que llamé setContentView ())

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top