美文网首页android技术Android基础架构
Android 多语言切换无需重启APP的方式

Android 多语言切换无需重启APP的方式

作者: 隐姓埋名的猫大叔 | 来源:发表于2020-08-19 21:47 被阅读0次

    简述

    当APP需要给提供多种语音供用户使用的时候,作为开发者的我们自然要涉及到多语言切换的开发,希望我提供的方式能给需要的小伙伴们一点思路,老规矩先上图。

    效果如下,可能看起来会比较卡(不知道为啥黑屏时间卡了好久,实际效果是一闪而过)


    效果图.gif

    实现方式

    这是最常运用的最普遍的方式,通过创建不同的value 语言文件夹下的的string.xml ,当更改时,切换使用对应的字符资源。
    让我们先来创建对应的字符资源文件夹。在main目录下的res文件夹右键新建一个资源文件夹


    操作截图1.png

    选中Locale,导入限定资源里


    操作截图2.png

    此时会出现各种语言资源,在此项目中,我将新增中文(zh)与英文(en)字符资源 (懒得找的小伙伴其实只要知道对应的语言文化代码,直接自己创建命名也可)


    操作截图3.png

    建完之后的目录:


    操作截图4.png

    接着再导入本次要使用的EventBus,用于广播通知(也可用Broadcast,这次主要是对于语言切换的实现,故不展开讲)

    implementation 'org.greenrobot:eventbus:3.0.0'
    

    然后我们先来实现一个抽象基类:BaseActivity,让其它Activity继承其特性,写一些共有方法,便于我们维护何使用,这里是为了实现多语言切换时,不用在每个Activity中实现切换语言通知时,界面重建与减少繁琐的编写EventBus 的订阅与注销

    public abstract class BaseActivity extends AppCompatActivity {
        public final static String SWITCH_LANGUAGE = "Language";
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setLanguage();
            EventBus.getDefault().register(this);
            setContentView(getViewResId());
            init();
        }
    
        protected void init() {
    
        }
    
        protected abstract int getViewResId();
    
    
    
        @Override
        protected void onDestroy() {
            EventBus.getDefault().unregister(this);
            super.onDestroy();
    
        }
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onEvent(String msg) {
            switch (msg){
                case SWITCH_LANGUAGE:
                    setLanguage();
                    recreate();//刷新界面
                    break;
            }
    
        }
    
        private void setLanguage() {
            Locale myLocale = new Locale(SPUtils.getLanguage(this));
            Resources res = getResources();
            DisplayMetrics dm = res.getDisplayMetrics();
            Configuration conf = res.getConfiguration();
            conf.locale = myLocale;
            res.updateConfiguration(conf, dm);
        }
    
    
    }
    

    setLanguage()方法中设置了我们的地理语言环境,将我们设置Locale赋值给Configuration,设置为我们需要的语言环境,再调用 recreate()方法销毁界面再重新创建,此方法只有在API>26以上版本才存在。调用后新创建的活动的生命周期:onCreate->onStart->onResume
    其中SPUtils 工具类是用来在关闭应用后,重新打开我们的APP时,记录用户设置的切换语言类型(它本质就是一个小型数据库,随着应用卸载而被销毁)

    public class SPUtils {
        public static void setLanguage(Context context, String language) {
            SharedPreferences.Editor editor = context.getSharedPreferences("Language", context.MODE_PRIVATE).edit();
            editor.putString("language", language);
            editor.commit();
        }
    
        public static String getLanguage(Context context) {
            SharedPreferences editor = context.getSharedPreferences("Language", context.MODE_PRIVATE);
            return editor.getString("language","zh");//默认中文
        }
    }
    

    回到我们的主界面来,在XML上直接使用我们在strings中定义的内容,复制strings到对values-en 与 values-zh,自行修改中文与英文的的内容


    目录文件.png zh\string.png en\string.png

    在XML上的使用是通过@string/name 方式设置

    操作截图5.png

    在代码中则是通过调用Resources 的getString 方法获取对应资源文件的id来设置

    getResources().getString(R.string.to_one)
    

    现在我们通过跳转ActivityOne(记得要继承我们编写的基类)界面,点击按钮切换语言,XML布局就不给出了

    public class ActivityOne extends BaseActivity {
    
        @Override
        protected void init() {
            onClickEvent();
        }
    
        @Override
        protected int getViewResId() {
            return R.layout.activity_one;
        }
    
        private void onClickEvent() {
            findViewById(R.id.tv_chinese).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    SPUtils.setLanguage(ActivityOne.this, "zh");
                    EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
                }
            });
    
            findViewById(R.id.tv_english).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SPUtils.setLanguage(ActivityOne.this, "en");
                    EventBus.getDefault().post(BaseActivity.SWITCH_LANGUAGE);
                }
            });
        }
    }
    

    至此,就实现了语言切换的功能,录制图已贴在最顶部,当然切换方法还有其它方式,这里给出较为常用的一种,希望能给需要的小伙伴们一点启发。

    相关文章

      网友评论

        本文标题:Android 多语言切换无需重启APP的方式

        本文链接:https://www.haomeiwen.com/subject/nersdktx.html