Android 国际化中出现的坑

本文记录了在Android应用进行国际化时遇到的一个问题:系统语言切换后,RadioButton和CheckBox未跟随系统更新语言。问题出现在API 20及更低版本,原因在于setFreezesText(true)导致状态被强制保存。解决方法是在Activity的onResume()中重新设置控件文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在做应用的过程中,国际化可以说是我们都会接触的一块。在res文件夹下建立对应国家的values文件夹(可以参考国际化命名规则),里面放上各自语言的strings.xml文件即可

这里不讲国际化,只是记录系统语言发生改变时,应用中语言应用中出现的一个问题,也许还有其他也说不定。

问题

在应用界面打开系统设置更改系统语言,RadioButton 和 CheckBox 在重建之后没有更改语言

原因分析

以下是找的不同源码中的片段

Android 4.4.2 Api 19

@Override
public Parcelable onSaveInstanceState() {
    // Force our ancestor class to save its state
    setFreezesText(true);
    Parcelable superState = super.onSaveInstanceState();

    SavedState ss = new SavedState(superState);

    ss.checked = isChecked();
    return ss;
}

Android 4.4W.2 Api 20

@Override
public Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();

    SavedState ss = new SavedState(superState);

    ss.checked = isChecked();
    return ss;
}

Android 6.0 Api 23

@Override
public Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();

    SavedState ss = new SavedState(superState);

    ss.checked = isChecked();
    return ss;
}

从上可以看出,问题出现于Api 20以前,由于方法 setFreezesText(true),通过注释可以看出其作用是强制保存当前的状态;

解决方法

可以参考下面这个回答
Not all items in the layout update properly when switching locales
因为要翻墙,所以作了下摘录,如下:

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

    }
}

最直接简单粗暴的方式是:
在当前未改变的Activity的onResume()中找到未变化的控件设置其text即可,例如:

@Override
protected void onResume() {
    super.onResume();
    my_recorder.setText(R.string.my_recorder);
    recorder_manager.setText(R.string.recorder_manager);
    recorder_upload.setText(R.string.recorder_upload);
}

问题随时记录,方便日后查找回顾,谨记之。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值