Android本地化问题:在切换语言环境时,并非布局中的所有项目都能正确更新

这里的问题是:当我有一个活动在后台运行,我切换语言环境,我切换回应用程序,一切都更新…除了有一个“android:id”属性设置checkbox和单选button。

如果checkbox和单选button没有“android:id”属性,那么它们会更新OK。 其他字段没有这个问题,不pipe他们是否有“android:id”属性。

什么是最好的方式来确保我的跑步活动中的每一个地方被更改时更新?

重现步骤:

1)在Eclipse中创build一个“Hello,Android”项目。 2)在主布局中,定义两个checkbox:

<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)创build两个strings.xml:一个在“values”下,一个在“values-es”下面。

4)在“values”下创build以下string:

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

5)在“values-es”下创build以下string

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

6)将设备设置为“英文”

7)在仿真器或任何设备上运行应用程序(在HTC G1上testing)。

8)观察。 这两个checkbox都是“英文”。

9)按“Home”返回菜单,让应用程序在后台运行。

10)转到设置。 将语言切换到“español”

11)按住“Home”。 返回到应用程序。

预期结果:

两个checkbox都会显示“español”

实际结果:

首先checkbox显示“英文”

第二个checkbox显示“español”

看起来,具有“android:id”属性的checkbox没有更新,因为它应该。 没有“android:id”属性的checkbox按预期工作。

Solutions Collecting From Web of "Android本地化问题:在切换语言环境时,并非布局中的所有项目都能正确更新"

问题的原因是CompoundButton.onSaveInstanceState()调用setFreezesText(true) ,从而保存并恢复文本。

一个简单的解决scheme是使用这样的子类:

 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 } } 

这是一个迷人的错误。 我可以在我的Nexus One上重现它。

这似乎是在onSaveInstanceState()的默认实现。 如果你重写那个是没有操作(不链接到超类),问题就消失了。

默认的onSaveInstanceState()应该可以处理像checkbox状态这样的东西,但是它们必须已经搞砸了,并且也保存了文本。

所以,你有几个解决方法:

  1. 重写onSaveInstanceState()并且不链接到超类。 然而,这消除了您通常会获得的任何自动状态保存。
  2. onRestoreInstanceState() (…我认为…),链接到超类后,调用您的受影响的小部件的setText()正确的string资源,将其重置为正确的值。

当我有机会的时候,我会尽力跟进这个更多的明天。 我想检查源代码,并可能将其作为一个问题。

如果其中一些在内存中,他们不会改变。 如果你重新启动手机,重新安装应用程序或至less完全杀了应用程序,它会正常工作。

这2年旧票提出了一个不使用android:id的解决方法,所以我通过使用类似的布局解决了这个问题:

 <?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> 

所以现在得到RadioButton我使用这样的东西:

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

所以我可以以编程方式设置属性。