You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需获取所有视图及按钮ID实现Android应用语言切换的方案咨询

安卓无需逐个更新控件的全局语言切换解决方案

原方案失效原因

你直接修改Configuration的代码不会生效有两个核心问题:

  1. 你创建了携带新Locale的Context,但没有替换当前Activity正在使用的上下文,当前页面加载资源还是用的旧Locale的Context
  2. 没有触发Activity重新加载布局,系统不会自动刷新现有控件的文本内容,updateConfiguration方法在安卓7.0以上已经被废弃,高版本系统不会响应这个修改。

完整实现步骤

安卓系统本身支持多语言资源匹配,只要你把对应语言的字符串放在对应资源目录下,只要全局修改了App的Locale配置,并且让Activity使用新Locale的Context重新加载布局,所有引用了@string资源的控件会自动加载对应语言的文本,完全不需要手动挨个赋值。

1. 封装Locale持久化和上下文替换工具类

首先创建LocaleHelper工具类,用于保存选中的语言、以及替换Activity的上下文:

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import java.util.Locale;

public class LocaleHelper {
    private static final String PREF_LANG = "selected_lang";
    private static final String PREF_NAME = "lang_pref";

    // 保存选中的语言到本地
    public static void saveLocale(Context context, String langCode) {
        SharedPreferences sp = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        sp.edit().putString(PREF_LANG, langCode).apply();
    }

    // 获取本地保存的语言,默认返回英文
    public static String getSavedLocale(Context context) {
        SharedPreferences sp = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        return sp.getString(PREF_LANG, "en");
    }

    // 替换上下文为指定语言的Context
    public static Context attachBaseContext(Context context) {
        String langCode = getSavedLocale(context);
        Locale locale = new Locale(langCode);
        Locale.setDefault(locale);
        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            config.setLocale(locale);
            return context.createConfigurationContext(config);
        } else {
            config.locale = locale;
            resources.updateConfiguration(config, resources.getDisplayMetrics());
            return context;
        }
    }
}

2. 重写Activity的attachBaseContext方法

所有需要支持多语言的Activity都要重写这个方法,替换上下文:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(LocaleHelper.attachBaseContext(newBase));
}

3. 选中语言后重启Activity即可自动刷新所有文本

不需要再逐个给控件赋值,只需要保存选中的语言后调用recreate()重启Activity,系统会自动加载对应语言的所有资源:
修改后的MainActivity完整代码:

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 这里加载布局的时候会自动用当前Locale的资源,不需要手动赋值
        setContentView(R.layout.activity_main);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.language);
        builder.setCancelable(false);
        builder.setItems(R.array.languages, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                String[] languages_array = getResources().getStringArray(R.array.languages);
                String langCode = languages_array[which].equals("Chichewa") ? "ny" : "en";
                // 保存选中的语言
                LocaleHelper.saveLocale(MainActivity.this, langCode);
                // 重启Activity,自动加载新语言资源
                recreate();
            }});
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(LocaleHelper.attachBaseContext(newBase));
    }
}

注意事项

  • 所有页面的文本必须引用@string/xxx资源,不能在布局或者代码里硬编码写死文字
  • 对应语言的字符串要放到对应资源目录下,比如齐切瓦语的字符串放到res/values-ny/strings.xml,英文放到res/values-en/strings.xml
  • 如果需要全局所有页面都生效,可以在重启Activity的时候清空回退栈,重新打开首页,避免之前打开的页面还是旧语言

内容的提问来源于stack exchange,提问作者lewis machilika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:06:00