【问题标题】:Android Localization problem: Not all items in the layout update properly when switching localesAndroid本地化问题:切换语言环境时并非布局中的所有项目都正确更新
【发布时间】:2010-12-21 21:23:15
【问题描述】:

问题是:当我有一个在后台运行的活动时,我切换了区域设置,然后切换回应用程序,所有内容都会更新...除了具有“android:id”属性集的复选框和单选按钮.

如果复选框和单选按钮没有“android:id”属性,那么它们会更新 OK。其他字段不存在这个问题,不管有没有“android:id”属性。

确保在更改区域设置时更新我的​​跑步活动中的所有内容的最佳方法是什么?

重现步骤:

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

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

4) 在“values”下创建以下字符串:

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

5) 在“values-es”下创建如下字符串

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

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

7) 在模拟器或任何设备上运行应用程序(在 HTC G1 上测试)。

8) 观察。两个复选框都显示“英语”。

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

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

11) 按住“主页”。返回应用程序。

预期结果:

两个复选框都写着“español”

实际结果:

第一个复选框显示“英语”

第二个复选框显示“español”

带有“android:id”属性的复选框似乎没有按应有的方式更新。没有“android:id”属性的复选框按预期工作。

【问题讨论】:

标签: android layout localization


【解决方案1】:

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

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

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

    }
}

【讨论】:

  • 这个答案解决了我的问题。谢谢你节省了我的时间:)
【解决方案2】:

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

它似乎在onSaveInstanceState() 的默认实现中。如果您将其覆盖为无操作(不要链接到超类),问题就会消失。

默认的 onSaveInstanceState() 应该处理复选框状态之类的东西,但他们肯定搞砸了,并且也在保存文本。

因此,您有几个解决方法:

  1. 覆盖onSaveInstanceState() 并且不要链接到超类。但是,这消除了您通常会获得的任何自动状态保存。
  2. onRestoreInstanceState()(...我认为...)中,链接到超类后,使用正确的字符串资源在受影响的小部件上调用setText(),将其重置回正确的值。

我会在明天有机会时尝试更多地跟进。我想检查源代码并可能将此作为问题提交。

【讨论】:

  • 好吧,我无法在模拟器中的 Android 2.3 上重现此问题,而且我在源代码中看不到这是如何发生的。目前,我假设这个问题在 Android 2.3 中已经修复。我上面的解决方法应该仍然有效。
  • 我还注意到覆盖 onSaveInstanceState() 也“修复”了问题,尽管它确实具有禁用状态保存的不良副作用。我喜欢你在受影响的小部件上调用 setText() 的建议。
  • 不过,我仍然能够在 Android 2.3 模拟器中重现这一点。
  • @Kevin:真的吗?我试图在 Android 2.3 模拟器中重现它并失败了。有没有办法可以压缩您的项目源代码并将其发布到某个地方,将链接放在评论中?如果您和我使用相同的代码,我会感觉更舒服,而且由于您的代码似乎经常失败,我建议使用它。
  • @CommonsWare:你能试试这里附加的项目吗? code.google.com/p/android/issues/detail?id=13252 感谢您查看此内容!
【解决方案3】:

如果其中一些在内存中,它们将不会改变。如果您重新启动手机,重新安装应用程序或至少完全关闭应用程序,它会正常工作。

【讨论】:

  • AFAIK,区域设置更改是配置更改,因此应在销毁和重新创建活动时替换字符串。
  • 好吧......我已经看到了一些字符串挂起的相同行为。可能存在一些应用程序上下文加载或缓存。我只知道重新部署或重新启动应用程序总是可以修复它。
  • 是的,我尝试了其他一些元素,例如 TextView 并且字符串都正确更新,无论它们是否有 ID。只是复选框和单选按钮似乎有问题。
【解决方案4】:

2 years old ticket 提出了一个不使用 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;
}

所以我可以通过编程设置属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多