技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 学习资料

  • 技术选型

  • 要点

  • 经验

    • flutter文本
    • Android原生对flutter侧切换语言的适配
      • 优化
  • flutter
  • 经验
hss01248
2025-12-24
目录

Android原生对flutter侧切换语言的适配

# Android原生对flutter侧切换语言的适配

# flutter侧切换语言的实现

import 'package:pkg_base_lib/kv_storage/kv_util.dart';

class LanguageUtil{

  static Function? onLanguageChanged;
  static bool defaultEn = false;

  static void save(bool isEn){
    KvUtil.saveBool("local_is_en", isEn);
    onLanguageChanged?.call();
  }

  ///默认为英语
  static bool isEn(){
    return KvUtil.getBool("local_is_en",defValue: defaultEn)??defaultEn;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

在getx的初始化时设置:

        var getApp = GetMaterialApp(
          locale: LanguageUtil.isEn() ?  const Locale('en', 'US') : const Locale('id', 'ID') 
          ...)
1
2
3

切换语言时:

 //切换到英语
onTap: () {
                            var locale = const Locale('en', 'US');
                            LanguageUtil.save(true);
                            Get.updateLocale(locale);
                            logic.isEnglishLanguage.value = true;
                            RouterApi.back(result: 'English');
                          }
1
2
3
4
5
6
7
8

# Android侧的适配

flutter切换语言后,保存到原生的sharedprefences中

Android通过监听sharedprefences对应的key的值的变更,实时修改application和activity里的locale值:

flutter的容器activity里:

public class MainActivity extends FlutterFragmentActivity {

    SharedPreferences.OnSharedPreferenceChangeListener listener;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        updateResources(this,getLocale(this));
        listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
                LogUtils.v("onSharedPreferenceChanged",s);
                if("flutter.local_is_en".equals(s)){
                  //更新当前容器activity
                    updateResources(MainActivity.this,getLocale(MainActivity.this));
                   //更新application的locale updateResources(MainActivity.this.getApplicationContext(),getLocale(MainActivity.this));
                }
            }
        };
        getSharedPreferences("FlutterSharedPreferences",MODE_PRIVATE)
                .registerOnSharedPreferenceChangeListener(listener);
       
    }
  
  @Override
    protected void onDestroy() {
        super.onDestroy();
        getSharedPreferences("FlutterSharedPreferences",MODE_PRIVATE)
                .unregisterOnSharedPreferenceChangeListener(listener);
    }
  
      @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(updateResources(newBase,getLocale(newBase)));
    }
  
      private String getLocale(Context context) {
        boolean isEn = context.getSharedPreferences("FlutterSharedPreferences",MODE_PRIVATE)
                .getBoolean("flutter.local_is_en",AppType.ph());
        LogUtils.d("onSharedPreferenceChanged","language changed = "+isEn);
        return isEn ? "en" : "id";
    }

    private static Context updateResources(Context context, String language) {
        Resources res = context.getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        Locale locale = new Locale(language);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            LocaleList defaultList = LocaleList.forLanguageTags(language);
            LocaleList.setDefault(defaultList);
            conf.setLocales(defaultList);
        } else {
            conf.locale = locale;
        }
        conf.locale = locale;
        conf.setLocale(locale);
        context = context.createConfigurationContext(conf);
        res.updateConfiguration(conf, dm);
        return context;
    }
  }
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

并且,启动app时:

要根据sharedprefences存储的语言类型,设置好application的locale值,并利用activityCallbacks,在每个activity oncreated时,实时修改其locale值

为什么要对application和activity同时设置? 因为很多库的从resource id 取翻译用的context不一样,有的用application,有的用activity

示例代码:

    private void registerActivityCallbacks() {
        updateAppLocal(this);
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
                try{
                  //主要是为了应对一些其他原生页面的多语言
                    updateAppLocal(activity);
                }catch (Throwable throwable){
                    LogUtils.w(throwable);
                }

            }

            @Override
            public void onActivityStarted(@NonNull Activity activity) {

            }

            @Override
            public void onActivityResumed(@NonNull Activity activity) {

            }

            @Override
            public void onActivityPaused(@NonNull Activity activity) {

            }

            @Override
            public void onActivityStopped(@NonNull Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(@NonNull Activity activity) {

            }
        });
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    public static void updateAppLocal(Context context) {
        XLogUtil.d("updateAppLocal");
        Resources resources = context.getResources();
        Configuration config = resources.getConfiguration();
        DisplayMetrics dm = resources.getDisplayMetrics();

        //异步会导致有的手机上页面来不及响应,菲律宾显示印尼语,所以需要同步
        boolean isEn = context.getApplicationContext()
                .getSharedPreferences("FlutterSharedPreferences",MODE_PRIVATE)
                .getBoolean("flutter.local_is_en",AppType.phMitraApp()||AppType.phSaApp());
        Locale locale = isEn ? Locale.US : new Locale("id","IN");
        XLogUtil.d("updateAppLocal--->"+locale);
        config.setLocale(locale);
        resources.updateConfiguration(config, dm);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 优化

其实全部代码写到application里也是可以的,sharedPreferences的监听也能写到application里,有改变时,对activity栈里所有activity重新设置一遍locale

编辑 (opens new window)
flutter文本

← flutter文本

最近更新
01
motion photo的压缩
10-10
02
360全景图的压缩
10-10
03
360全景图的展示
10-10
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式