2010-12-21 4 views
10

Aquí está el problema: cuando tengo una actividad ejecutándose en segundo plano, cambio de configuración regional y cambio a la aplicación, todo se actualiza ... EXCEPTO casillas de verificación y botones de radio que tienen un conjunto de atributos "android: id".Problema de localización de Android: no todos los elementos del diseño se actualizan correctamente al cambiar de configuración

Si las casillas de verificación y los botones de opción no tienen el atributo "android: id", entonces se actualizan correctamente. Otros campos no tienen este problema, ya sea que tengan un atributo "android: id" o no.

¿Cuál es la mejor manera de asegurarse de que todo en mi actividad de ejecución se actualice cada vez que se cambie la configuración regional?

Pasos para reproducir:

1) crear un "Hola, Android" proyecto en Eclipse. 2) En la disposición principal, definir dos casillas de verificación:

<CheckBox android:text="@string/checkbox" android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox> 
<CheckBox android:text="@string/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox> 

3) crear dos strings.xml: uno bajo "valores" y uno bajo "valores-ES".

4) Crear la siguiente cadena en "valores":

<string name="checkbox">English</string> 

5) Crear la siguiente cadena en "valores-es"

<string name="checkbox">español</string> 

6) Dispositivo de Ajuste a “Inglés”

7) Ejecute la aplicación en el emulador o en cualquier dispositivo (probado en HTC G1).

8) Observe. Ambas casillas de verificación dicen "inglés".

9) Presione "Inicio" para volver al menú y dejar la aplicación ejecutándose en segundo plano.

10) Ir a la configuración. Cambiar el idioma a “español"

11) Mantenga pulsado ‘Inicio’ volver a la aplicación

Resultado esperado:..

Ambas casillas de verificación dicen ‘español’

Resultado real:

primera casilla de verificación dice “Inglés”

casilla segundo dice “español”

Parece que la casilla de verificación con un atributo "android: id" no se está actualizando como debería. La casilla de verificación sin el atributo "android: id" funciona como se esperaba.

+1

Un parche para corregir este comportamiento se han fusionado para dominar rama. Consulte https://android-review.googlesource.com/#/c/67850/ – victor

Respuesta

0

Si algunos de ellos están en la memoria, no cambiarán. Si reinicias el teléfono, vuelves a instalar la aplicación o al menos matas por completo la aplicación, funcionará bien.

+0

AFAIK, los cambios de configuración regional son cambios de configuración y, por lo tanto, las cadenas deben reemplazarse cuando la actividad se destruye y se vuelve a crear. – CommonsWare

+0

bueno ... He visto el mismo comportamiento que algunas cadenas. Puede haber alguna carga de contexto de aplicación o almacenamiento en caché. Solo sé que una aplicación volver a implementar o reiniciar siempre lo corrige. –

+0

Sí, lo intenté con algunos otros elementos, como TextView, y las cadenas se actualizaron correctamente tanto si tenían una identificación como si no. Solo son casillas de verificación y botones de radio que parecen tener un problema. – Kevin

5

Eso es un error fascinante. Puedo reproducirlo en mi Nexus One.

Parece estar en la implementación predeterminada de onSaveInstanceState().Si anulas eso para que no funcione (no encadenas a la superclase), el problema desaparece.

Se supone que el onSaveInstanceState() predeterminado maneja cosas como el estado de la casilla de verificación, pero deben haber estropeado eso y están guardando el texto también.

Por lo tanto, usted tiene un par de soluciones:

  1. onSaveInstanceState() de anulación y no lo hace la cadena a la superclase. Esto, sin embargo, elimina cualquier ahorro de estado automático que normalmente obtendría.
  2. En onRestoreInstanceState() (... Creo ...), después de encadenar a la superclase, llame al setText() en sus widgets afectados con el recurso de cadena adecuado, para restablecerlo de nuevo al valor correcto.

Trataré de darle seguimiento a esto más mañana cuando tenga la oportunidad. Quiero verificar el código fuente y probablemente presentar esto como un problema.

+0

Bueno, no puedo reproducir este problema en Android 2.3 en el emulador, y no veo en el código fuente cómo podría estar ocurriendo. Por el momento, asumiré que este problema está solucionado en Android 2.3. Mis soluciones anteriores aún deberían ser válidas. – CommonsWare

+0

También noté que anular el onSaveInstanceState() también "solucionó" el problema, aunque tiene el efecto secundario negativo de deshabilitar el ahorro de estado. Me gusta su sugerencia de llamar a setText() en los widgets afectados. – Kevin

+0

Todavía puedo reproducir esto en el emulador de Android 2.3. – Kevin

0

Este 2 years old ticket propone una solución alternativa de no usar el androide: id por lo que corrige este problema utilizando un diseño similar:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"> 

    <!-- KEEP THIS ALWAYS THE FIRST because it dosen't have 
     an android:id as a workaround of this bug 
     https://code.google.com/p/android/issues/detail?id=13252 
     --> 
    <RadioButton xmlns:android="http://schemas.android.com/apk/res/android" /> 

    <!-- other elements --> 

</RelativeLayout> 

Así que ahora para obtener el RadioButton utilizo algo como esto:

private RadioButton getButton(RelativeLayout layout) { 
    RadioButton button = null; 
    if (layout.getChildCount() != 0) { 
     button = (RadioButton) layout.getChildAt(0); 
    } 
    return button; 
} 

Para que pueda establecer las propiedades mediante programación.

8

La causa del problema es que CompoundButton.onSaveInstanceState() llama a setFreezesText(true) y así guarda & restaura el texto.

Una solución sencilla utiliza una subclase de esta manera:

public class CheckBoxNoPersistentText extends CheckBox { 

    public CheckBoxNoPersistentText(final Context context) { 
     super(context); 
    } 

    public CheckBoxNoPersistentText(final Context context, final AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public CheckBoxNoPersistentText(final Context context, final AttributeSet attrs, final int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public void onRestoreInstanceState(final Parcelable state) { 

     final CharSequence text = getText(); // the text has been resolved anew 

     super.onRestoreInstanceState(state); // this restores the old text 

     setText(text); // this overwrites the restored text with the newly resolved text 

    } 
} 
Cuestiones relacionadas