• Android中的多语言切换,对于我们应用层的开发同学来时,操作起来非常见到,代码也很简单,大部分工作都是让framwork层的资源进程调度框架给代工了。OK,下面我们一步步看看怎么完成多语言配置和切换:1.右击res...

    在一些应用需要国际化或者面对各种用户群体时,会涉及到语言的不同,所以我们在开发应用apk时,记得一定要养成将应用中涉及到的所有文字信息放在string.xml里的好习惯!Android中的多语言切换,对于我们应用层的开发同学来时,操作起来非常见到,代码也很简单,大部分工作都是让framwork层的资源进程调度框架给代工了。OK,下面我们一步步看看怎么完成多语言的配置和切换:

    1.右击res目录,打开对应的对话框:
    这里写图片描述

    2.选择local选项,然后点击右推的按钮,创建和选择新的语言资源文件,注意以下这几个地方需要正确填写:

    这里写图片描述

    这里写图片描述

    然后点击ok就会开发项目目录中多了一个文件夹和文件:

    这里写图片描述

    3.接着把默认的values/strings.xml中的内容全部复制到values-en/strings.xml中,然后把内容中的文字顺便翻译成对应的语言:

    这里写图片描述
    这里写图片描述

    4.接下来就是在activity中引用和设置的操作了:

    首先需要定义一个全局变量存放activity栈和选择的语言类别:

    public class Constants {
        //系统默认是zh的类型
        public static String langae = "zh";
        public static List<Activity> activityList = new ArrayList<>();
    }

    MainActivity.java中:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Constants.activityList.add(this);
            switchLanguage(Constants.langae);
        }
        public void onclick(View view) {
            startActivity(new Intent(this, SecendActivity.class));
        }
        //核心设置的代码
        protected void switchLanguage(String language) {
            Resources resources = getResources();
            Configuration config = resources.getConfiguration();
            DisplayMetrics dm = resources.getDisplayMetrics();
            switch (language) {
                case "zh":
                    config.locale = Locale.CHINESE;
                    resources.updateConfiguration(config, dm);
                    break;
                case "en":
                    config.locale = Locale.ENGLISH;
                    resources.updateConfiguration(config, dm);
                    break;
                default:
                    config.locale = Locale.US;
                    resources.updateConfiguration(config, dm);
                    break;
            }
        }
    }

    在onCreate()中设置语言的默认值。

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@color/colorPrimary"
            android:onClick="onclick"
            android:padding="10dp"
            android:text="@string/lanage"
            android:textColor="#fff" />
    
    </RelativeLayout>

    SecendActivity.xml:

    public class SecendActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.atty_secend_layout);
    
            Constants.activityList.add(this);
    
            RadioGroup radio = (RadioGroup) findViewById(R.id.radio);
            final RadioButton radioButtonen = (RadioButton) findViewById(R.id.radio_en);
            final RadioButton radioButtonzh = (RadioButton) findViewById(R.id.radio_zh);
    
            if (Constants.langae.equals("zh")) {
                radioButtonzh.setChecked(true);
            } else {
                radioButtonen.setChecked(true);
            }
    
            radio.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    if (checkedId == R.id.radio_zh) {
                        Constants.langae = "zh";
                        radioButtonen.setChecked(false);
                    } else {
                        radioButtonzh.setChecked(false);
                        Constants.langae = "en";
                    }
                }
            });
        }
    
        public void onClick(View view) {
            Locale locale = new Locale(Constants.langae);
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            Resources resources = getResources();
            resources.updateConfiguration(config, resources.getDisplayMetrics());
    
            //让之前打开的所有界面全部彻底关闭
            for (Activity activity : Constants.activityList) {
                activity.finish();
            }
            //回到应用的首页
            startActivity(new Intent(this, MainActivity.class));
        }
    }

    atty_secend_layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <RadioGroup
            android:id="@+id/radio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="100dp"
            android:orientation="horizontal">
    
            <RadioButton
                android:id="@+id/radio_zh"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="@string/zh" />
    
            <RadioButton
                android:id="@+id/radio_en"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="50dp"
                android:text="@string/en" />
    
        </RadioGroup>
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@color/colorPrimary"
            android:onClick="onClick"
            android:padding="10dp"
            android:text="@string/click"
            android:textColor="#fff" />
    
    </RelativeLayout>

    5.写完代码后,我们运行看看:

    设置前:
    这里写图片描述 这里写图片描述

    设置后:
    这里写图片描述 这里写图片描述

    展开全文
  • APP为什么要做多语言?  首先如果APP的用户量超级多,并且不只在内地使用,海外也有市场。那么来自各个不同国家和地区的人使用的时候,肯定想把这个APP设置成他所熟悉的语言,比如微信,微博,支付宝等这些APP都...

    此文属于finddreams的原创博客,转载请注明出处:http://blog.csdn.net/finddreams/article/details/78470768

      APP为什么要做多语言?

      首先如果APP的用户量超级多,并且不只在内地使用,海外也有市场。那么来自各个不同国家和地区的人使用的时候,肯定想把这个APP设置成他所熟悉的语言,比如微信,微博,支付宝等这些APP都支持多语言设置的。

      此外还有一些股票类的APP,因为股票类的APP所提供的行情报价服务包含了各大证券市场的,有内地的上证指数,深圳指数,还有香港的恒生指数,以及美股的纳斯达克和道琼斯指数等等。这些不同市场的指数涵盖了中文简体和繁体,还有英文的使用人群。所以股票类APP为了更符合当地人的语言习惯,多语言(国际化)则是必然要做的事情。这类APP有大智慧,同花顺,富途牛牛等。

      笔者所在公司的产品也是做股票类的,主要面向的用户是香港地区,所以支持繁体和英文多语言切换也是刚需了。

      说到要做多语言,刚开始我们原生这边就觉得这不是Android系统自带就支持的东西吗?在res资源目录下新建不同语言的values文件名,Android系统就会自动的去找对应的语言包下的string显示出来,这应该不难吧?

      于是在网上看了一些教程之后,就开始干了起来。结果在实际的开发过程中遇到了很多的问题,比如说Android7.0 的兼容性问题,以及在试用微信的Tinker热修复中遇到语言切换失效的问题等。接下来就来谈一谈笔者在APP多语言过程中的一些经验分享,希望能够帮到大家。

                               示例项目的效果图
                   这里写图片描述

    APP多语言需要原生和后台都要做改动

      后台的话,需要跟随客户端的语言来返回对应的语言数据,比如在客户端设置成简体的情况下,返回简体的数据,繁体的情况,则返回繁体数据。这就需要客户端在每次初始化和切换语言之后把请求接口中的语言参数改成对应的语言code,后台根据客户端的请求中所带的语言参数来决定返回什么样的语言。后台返回的语言数据,除了某些特别的词语为了符合本地的语言习惯,手动配置的,其他的简繁体词语,英文都是通过机器翻译的。

    重点说一下原生Android的多语言的做法

      1. 因为以前我们的字符串都是写死在Java代码中或者layout布局文件中的,这样的话就不可以根据多语言设置来变化,同时也比较难维护。

      所以首先我们要把Java代码和layout布局文件中的写死的字符串硬编码抽取出来,统一的放到values/strings.xml的文件里面,这样就能为不同语言的values文件的strings.xml打下基础,这是前提条件。这也告诉我们在平时的开发中要注意到这一点,养成把字符串配置在strings.xml文件里面的习惯,维护起来方便,将来如果要做多语言的话也不用费时费力的把那些写死的字符串抽出来了,省了很多无脑的操作。

      2. 新建一个你需要支持的语言包资源文件,比如values目录可以放默认的中文简体strings.xml文件,values-en则是放置英文版的strings,values-zh-rHK和values-zh-tTW这两个资源文件夹分别代表香港和台湾,台湾默认的语言是繁体,香港也有繁体的使用习惯,所以这两个文件里面放的strings.xml几乎都是一样的,但其实地方不一样,本地的语言习惯也是有一些区别的。比如我们写的博客用香港的繁体写也是博客,但是台湾人习惯称之为部落格(blog)。

    res下的多语言资源文件如下图:

    这里写图片描述

      3. 多语言资源包配置好了之后,就是语言切换的代码编写了,

    package com.finddreams.languagelib;
    
    import android.content.Context;
    import android.content.res.Configuration;
    import android.content.res.Resources;
    import android.os.Build;
    import android.text.TextUtils;
    import android.util.DisplayMetrics;
    import android.util.Log;
    
    
    import org.greenrobot.eventbus.EventBus;
    
    import java.util.Locale;
    
    /**
     * 多语言切换的帮助类
     * http://blog.csdn.net/finddreams
     */
    public class MultiLanguageUtil {
    
        private static final String TAG = "MultiLanguageUtil";
        private static MultiLanguageUtil instance;
        private Context mContext;
        public static final String SAVE_LANGUAGE = "save_language";
    
        public static void init(Context mContext) {
            if (instance == null) {
                synchronized (MultiLanguageUtil.class) {
                    if (instance == null) {
                        instance = new MultiLanguageUtil(mContext);
                    }
                }
            }
        }
    
        public static MultiLanguageUtil getInstance() {
            if (instance == null) {
                throw new IllegalStateException("You must be init MultiLanguageUtil first");
            }
            return instance;
        }
    
        private MultiLanguageUtil(Context context) {
            this.mContext = context;
        }
    
        /**
         * 设置语言
         */
        public void setConfiguration() {
            Locale targetLocale = getLanguageLocale();
            Configuration configuration = mContext.getResources().getConfiguration();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                configuration.setLocale(targetLocale);
            } else {
                configuration.locale = targetLocale;
            }
            Resources resources = mContext.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            resources.updateConfiguration(configuration, dm);//语言更换生效的代码!
        }
    
        /**
         * 如果不是英文、简体中文、繁体中文,默认返回简体中文
         *
         * @return
         */
        private Locale getLanguageLocale() {
            int languageType = CommSharedUtil.getInstance(mContext).getInt(MultiLanguageUtil.SAVE_LANGUAGE, 0);
            if (languageType == LanguageType.LANGUAGE_FOLLOW_SYSTEM) {
                Locale sysType = getSysLocale();
                if (sysType.equals(Locale.ENGLISH)) {
                    return Locale.ENGLISH;
                } else if (sysType.equals(Locale.TRADITIONAL_CHINESE)) {
                    return Locale.TRADITIONAL_CHINESE;
                } else if (TextUtils.equals(sysType.getLanguage(), Locale.CHINA.getLanguage())) { //zh
                    if (TextUtils.equals(sysType.getCountry(), Locale.CHINA.getCountry())) {  //适配华为mate9  zh_CN_#Hans
                        return Locale.SIMPLIFIED_CHINESE;
                    }
                } else {
                    return Locale.SIMPLIFIED_CHINESE;
                }
            } else if (languageType == LanguageType.LANGUAGE_EN) {
                return Locale.ENGLISH;
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_SIMPLIFIED) {
                return Locale.SIMPLIFIED_CHINESE;
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_TRADITIONAL) {
                return Locale.TRADITIONAL_CHINESE;
            }
            Log.e(TAG, "getLanguageLocale" + languageType + languageType);
            getSystemLanguage(getSysLocale());
            return Locale.SIMPLIFIED_CHINESE;
        }
    
        private String getSystemLanguage(Locale locale) {
            return locale.getLanguage() + "_" + locale.getCountry();
    
        }
    
        //7.0以上获取方式需要特殊处理一下
        public Locale getSysLocale() {
            if (Build.VERSION.SDK_INT < 24) {
                return mContext.getResources().getConfiguration().locale;
            } else {
                return mContext.getResources().getConfiguration().getLocales().get(0);
            }
        }
    
        /**
         * 更新语言
         *
         * @param languageType
         */
        public void updateLanguage(int languageType) {
            CommSharedUtil.getInstance(mContext).putInt(MultiLanguageUtil.SAVE_LANGUAGE, languageType);
            MultiLanguageUtil.getInstance().setConfiguration();
            EventBus.getDefault().post(new OnChangeLanguageEvent(languageType));
        }
    
        public String getLanguageName(Context context) {
            int languageType = CommSharedUtil.getInstance(context).getInt(MultiLanguageUtil.SAVE_LANGUAGE,LanguageType.LANGUAGE_FOLLOW_SYSTEM);
            if (languageType == LanguageType.LANGUAGE_EN) {
                return mContext.getString(R.string.setting_language_english);
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_SIMPLIFIED) {
                return mContext.getString(R.string.setting_simplified_chinese);
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_TRADITIONAL) {
                return mContext.getString(R.string.setting_traditional_chinese);
            }
            return mContext.getString(R.string.setting_language_auto);
        }
    
        /**
         * 获取到用户保存的语言类型
         * @return
         */
        public int getLanguageType() {
            int languageType = CommSharedUtil.getInstance(mContext).getInt(MultiLanguageUtil.SAVE_LANGUAGE, LanguageType.LANGUAGE_FOLLOW_SYSTEM);
             if (languageType == LanguageType.LANGUAGE_CHINESE_SIMPLIFIED) {
                return LanguageType.LANGUAGE_CHINESE_SIMPLIFIED;
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_TRADITIONAL) {
                return LanguageType.LANGUAGE_CHINESE_TRADITIONAL;
            } else if (languageType == LanguageType.LANGUAGE_FOLLOW_SYSTEM) {
               return LanguageType.LANGUAGE_FOLLOW_SYSTEM;
            }
            Log.e(TAG, "getLanguageType" + languageType);
            return languageType;
        }
    }
    

      上面最关键的切换语言的代码是这个setConfiguration()是切换到对应的语言环境的方法,方法中通过Configuration对象来把语言对象locale设置进去,最后通过Resources对象来实现语言的更换生效。

    
       /**
         * 设置语言
         */
        public void setConfiguration() {
            Locale targetLocale = getLanguageLocale();
            Configuration configuration = mContext.getResources().getConfiguration();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                configuration.setLocale(targetLocale);
            } else {
                configuration.locale = targetLocale;
            }
            Resources resources = mContext.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            resources.updateConfiguration(configuration, dm);//语言更换生效的代码!
    
        }

      getLanguageLocale()方法先获取到用户保存在手机中的语言是什么,如果没有设置过则是默认跟随系统的语言设置来,getSysLocale()来获取到本地的语言locale对象,通过语言的判断来返回对应的语言locale对象,默认返回简体的locale对象,如果用户选择了英文则是返回英文的Locale.ENGLISH,同理返回其他对应语言的Locale对象。

    
        /**
         * 如果不是英文、简体中文、繁体中文,默认返回简体中文
         *
         * @return
         */
        private Locale getLanguageLocale() {
            int languageType = CommSharedUtil.getInstance(mContext).getInt(LanguageUtil.SAVE_LANGUAGE, 0);
            if (languageType == LanguageType.LANGUAGE_FOLLOW_SYSTEM) {
                Locale sysType = getSysLocale();
                if (sysType.equals(Locale.ENGLISH)) {
                    return Locale.ENGLISH;
                } else if (sysType.equals(Locale.TRADITIONAL_CHINESE)) {
                    return Locale.TRADITIONAL_CHINESE;
                } else if (TextUtils.equals(sysType.getLanguage(), Locale.CHINA.getLanguage())) { //zh
                    if (TextUtils.equals(sysType.getCountry(), Locale.CHINA.getCountry())) {  //适配华为mate9  zh_CN_#Hans
                        return Locale.SIMPLIFIED_CHINESE;
                    }
                } else {
                    return Locale.SIMPLIFIED_CHINESE;
                }
            } else if (languageType == LanguageType.LANGUAGE_EN) {
                return Locale.ENGLISH;
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_SIMPLIFIED) {
                return Locale.SIMPLIFIED_CHINESE;
            } else if (languageType == LanguageType.LANGUAGE_CHINESE_TRADITIONAL) {
                return Locale.TRADITIONAL_CHINESE;
            }
            Log.e(TAG, "getLanguageLocale" + languageType + languageType);
            getSystemLanguage(getSysLocale());
            return Locale.SIMPLIFIED_CHINESE;
        }

      在多语言切换选择的时候,调用updateLanguage方法来实现切换到用户选择的语言类型

     /**
         * 更新语言
         *
         * @param languageType
         */
        public void updateLanguage(int languageType) {
            CommSharedUtil.getInstance(mContext).putInt(LanguageUtil.SAVE_LANGUAGE, languageType);
            MultiLanguageUtil.getInstance().setConfiguration();
            EventBus.getDefault().post(new OnChangeLanguageEvent(languageType));
        }

      语言切换成功事件可以通过发生EventBus来通知想要知道这个事件的页面,来实现语言变化后刷新UI和更改请求接口中的语言参数重新请求服务端获取对应语言的数据来填充布局。

      4. 多语言切换功能一般出现在二三级页面,选择其他语言确认之后跳转到哪里? Android 中很多的APP的做法是直接跳转到首页,比如微信都是直接删除所有的activity同时跳转到首页,这样再次打开其他二级页面的时候就会重新初始化页面,重新加载语言当然也会跟着变化成用户选择的语言。当然返回上一级页面也是可以的,只是处理起来会比较麻烦,所以推荐还是微信的切换语言之后的做法。

    选择完语言确认的跳转逻辑如下:

     @Override
        public void onClick(View view) {
            int id = view.getId();
            int selectedLanguage = 0;
            switch (id) {
                case R.id.rl_followsytem:
                    setFollowSytemVisible();
                    selectedLanguage = LanguageType.LANGUAGE_FOLLOW_SYSTEM;
                    break;
                case R.id.rl_simplified_chinese:
                    setSimplifiedVisible();
                    selectedLanguage = LanguageType.LANGUAGE_CHINESE_SIMPLIFIED;
    
                    break;
                case R.id.rl_traditional_chinese:
                    setTraditionalVisible();
                    selectedLanguage = LanguageType.LANGUAGE_CHINESE_TRADITIONAL;
    
                    break;
                case R.id.rl_english:
                    setEnglishVisible();
                    selectedLanguage = LanguageType.LANGUAGE_EN;
                    break;
            }
            LanguageUtil.getInstance().updateLanguage(selectedLanguage);
            Intent intent = new Intent(SetLanguageActivity.this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intent);
            if (selectedLanguage == LanguageType.LANGUAGE_FOLLOW_SYSTEM) {
                System.exit(0);
            }
        }

      通过intent的 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK)来清除activity的栈,来打开MainActivity看起来像是重启的效果。这个跳转过程要做到尽量的平滑,不然会被产品经理刁飞的。另外设置跟随系统有些特别,如果不先退出整个APP再回到首页的话,则不会有切换语言的效果。

    多语言开发过程中的遇到的问题

      1. 横竖屏切换(屏幕旋转)导致多语言(国际化)的设置失效

      原因:当屏幕旋转横竖屏切换时,Activity的onConfigurationChanged方法使用了系统的语言设置,Activity中onConfigurationChanged的源码如下:

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            getDelegate().onConfigurationChanged(newConfig);
            if (mResources != null) {
                // The real (and thus managed) resources object was already updated
                // by ResourcesManager, so pull the current metrics from there.
                final DisplayMetrics newMetrics = super.getResources().getDisplayMetrics();
                mResources.updateConfiguration(newConfig, newMetrics);
            }
        }

      从上面的代码中我们可以看到newConfig取的是系统的,这就解释了为什么APP明明设置成了繁体,但是打开一个横屏页面之后,发现APP又重置成了简体,就是这个方法导致的。

      所以我们只需要在onConfigurationChanged方法中,重新设置为我们用户选择的语言配置就可以了。因为要在所有的Activity中的onConfigurationChanged中设置会有些麻烦,我们可以在application中的onConfigurationChanged方法中统一设置,这样就可以解决屏幕旋转造成的多语言失效问题。

     @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            MultiLanguageUtil.getInstance().setConfiguration();
        }

      2. 打开有 webview 的Activity会导致多语言失效,发生在Android7.0以上

      原因:可能是webview在加载的过程中也会重新设置系统的语言,这样因为打开网站可能有英文版的和中文的。
      解决方案,既然很多情况下都会造成多语言失效,不如我们统一在BaseActivity的onCreate方法中都设置

                    LanguageUtil.getInstance().setConfiguration();
    

    当然如果有些Activity不是继承子BaseActivity,我们依然可以在application中的onCreate方法中使用这样的方式来拿到整个应用的所有activity的生命周期方法,然后在这样设置:

     registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle bundle) {
    
                }
    
                @Override
                public void onActivityStarted(Activity activity) {
    
                }
    
                @Override
                public void onActivityResumed(Activity activity) {
                    MultiLanguageUtil.getInstance().setConfiguration();
                }
    
                @Override
                public void onActivityPaused(Activity activity) {
    
                }
    
                @Override
                public void onActivityStopped(Activity activity) {
    
                }
    
                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    
                }
    
                @Override
                public void onActivityDestroyed(Activity activity) {
    
                }
            });

      3. 使用微信开源的热修复框架Tinker,打了包含资源的补丁之后会导致多语言失效

      笔者在试用的过程中遇到如果打了包含资源string文件的补丁之后,会导致多语言失效,本来选的繁体变成了简体语言,同时无论你怎么切换语言,都没有生效。这属于Tinker的bug,已经有人在Tinker的github主页上反馈了,但是这个issue 任然没有关闭:https://github.com/Tencent/tinker/issues/302 。 后来因为担心热修复技术可能会存在其他兼容性问题,所以还没有用在公司的app上。但是“热修复不是请客吃饭”,感谢Tinker开发者的努力。

      多语言(国际化)过程虽然繁琐,充满了重复劳动,但总体来说不算难。最后附示例项目地址,欢迎大家提问
    https://github.com/finddreams/AndroidMultiLanguage

    展开全文
  • Android多语言设置在开发中时有用到,实现也不复杂,主要包括三个方面 不同语言的资源的实现,即string.xml的实现 利用Locale改变系统的语言设置 切换更新UI 首先需要将不同语言版本的资源配置好 首先要新建...

    原创文章,如有转载,请注明出处:http://blog.csdn.net/myth13141314/article/details/62037194

    Android 的多语言设置在开发中时有用到,实现也不复杂,主要包括三个方面

    • 不同语言的资源的实现,即string.xml的实现
    • 利用Locale改变系统的语言设置

    首先需要将不同语言版本的资源配置好


    这里写图片描述

    • 新建values文件夹,不同国家的文件夹名字不一样


      这里写图片描述

      这里写图片描述


    • 根据需要选择建立对应语言的资源文件夹,文件夹名称系统会自动生成


      这里写图片描述


    • 然后在对应的资源文件夹下面新建string.xml文件,不同语言的字符串资源的名称要一样,如下面的中文和英文:
    //英文资源
    <resources>
        <string name="app_language">language</string>
    </resources>
    
    //中文资源
    <resources>
        <string name="app_language">语言</string>
    </resources>

    通过以上步骤,资源文件已经准备好,接下去就是改变系统的语言环境,这就需要用到Locale

    • 生成新的Locale对象
    public Locale(String language, String country) {
            this(language, country, "");
    }
    
    //例如,生成English,不限地区的Locale对象
    new Locale("en", ")
    • 更改系统的语言设置
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = newLocale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());//更新配置
    • 需要注意的是,更改语言配置需要在MainActivity的setContentView()之前设置才会起作用
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initLocaleLanguage();
            setContentView(R.layout.activity_main);
        }
    }
    
    private void initLocaleLanguage() {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        configuration.locale = newLocale;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());//更新配置
    }

    一般的更改语言的选项都在App的设置里面,改变系统的Locale以后并不会马上生效,需要重启App以后才会有效。如果要及时生效,就需要重启MainActivity,方法如下:

    //重启MainActivity
    Intent intent = new Intent(SettingActivity.this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

    通过以上步骤,多语言的实现基本就Ok了,需要什么语言进行对应的设置即可,都是一样的思路。



    欢迎关注我的公众号,和我一起每天进步一点点!
    这里写图片描述

    展开全文
  • Android多语言设置

    2019-08-04 21:28:35
    如果Android应用需要做本地化,都要用到多语言来适配,例如手机设置成英文后,App内文字变成英文。 App提供资源可以参考官方文档...

    如果Android应用需要做本地化,都要用到多语言来适配,例如手机设置成英文后,App内文字变成英文。

    App提供资源可以参考官方文档https://developer.android.com/guide/topics/resources/providing-resources#AlternativeResources,App提供各种适配的资源,包括但不限定于:语言和区域,屏幕尺寸,屏幕像素密度。做多语言功能,提供values资源即可。例如中文:values-zh;中文简体:values-zh-rCH;中文繁体:values-zh-rTW;App查找资源可以参考文档https://developer.android.com/guide/topics/resources/providing-resources#BestMatch,而对于语言的资源匹配可以参考这个https://developer.android.com/guide/topics/resources/multilingual-support,7.0之前和之后有些许区别。

    这样设置基本实现了多语言,但是如果需要App内切换语言的功能的话需要设计应用内切换语言的代码。主要代码是更新Application和Activity的Resources的语言设置,在Application中的onCreate中更新Resources,在Activity中则需要在attachBaseContext中进行操作,在7.0之后有些许变化,

    7.0之前只更新Resources即可,代码如下

        private void setConfiguration(Context context) {
            Resources resources = context.getResources();
            Locale targetLocale = getLocale();
            Configuration configuration = resources.getConfiguration();
            configuration.locale = targetLocale;
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());//语言更换生效的代码!
        }

    7.0之后需要使用createConfigurationContext新建一个Context返回,代码如下

        private Context updateResources(Context context) {
            Resources resources = context.getResources();
            Locale locale = getLocale();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(locale);
            return context.createConfigurationContext(configuration);
        }

    getLocale就是获取当前选择的语言。如果是跟随系统则需要获取系统设置的语言,代码如下

        private static Locale getSystemLocale() {
            Locale locale;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多语言设置获取顶部的语言
                locale = Resources.getSystem().getConfiguration().getLocales().get(0);
            } else {
                locale = Resources.getSystem().getConfiguration().locale;
            }
            return locale;
        }

    每次选择后需要重建Activity,并更新Application的Resources,这时可以选择重建所有的Activity,或者返回MainActivity,只重建MainActivity。

    另外:如果在项目中配置了resConfigs,则需要添加自己多语言的配置,例如resConfigs("zh-rCN","zh-rTW","en")

    具体Demo可以参考https://github.com/jklwan/NoteApplication/blob/master/app/src/main/java/com/chends/note/utils/LanguageUtil.java

    展开全文
  • 一、生成对应语言文件夹 选中你的工程-&amp;amp;gt;res-&amp;amp;gt;右键点击new -&amp;amp;gt; 选中Android resource directory Available qualifiers:选择Locale, 点击 “&amp;amp;gt;&amp;...

    环境:
    Android studio 3.2
    执行步骤:
    一、生成对应语言文件夹

    1. 选中你的工程->res->右键点击new -> 选中Android resource directory 在这里插入图片描述
    2. Available qualifiers:选择Locale, 点击 “>>” 按钮 在这里插入图片描述
    3. AS3.0后没有快捷搜索功能,鼠标点击language列表,找到zh->在列表中找到TW:Taiwan在这里插入图片描述
    4. 点击OK就新建完成了,然后拷贝value目录下的strings.xml 到 values-zh-rTW目录里在这里插入图片描述
    5. 文件创建完成后,就可以简单的输入一些繁体字对应的字符串资源了。举例说明,“登录”这个字符资源,我们首先在values目录下的strings.xml中存入该中文字符串资源,并赋予id:login
      在这里插入图片描述
      在这里插入图片描述
    展开全文
  • Android studio进阶之多语言编程--国际化 前段时间接到一个关于PDA的项目 , 其中需要用到国际化 , 之前做Java 的时候是丢jar对应的国际化语言的jar .开发过程中踩了点,本文就是记录自己的开发过程. 国际化,听着...
  • Android动态设置多语言

    2017-01-06 16:18:53
    动态设置多语言效果图:需求:在设置中添加一个可以设置语言的需求,点击选中的语言,就可以切换显示。demo代码:APP类:app初始化的时候获取保存的语言(没有就系统默认),设置语言。public class APP extends ...
  • 最近接触到了项目需要,多语言的转换。网上有很多资料,我整理一些,简单适合自己使用的操作。 第一步:打开Android studio 添加Android Studio插件:AndroidLocalizationer File-----&gt;Setting------...
  • Android N 现在允许用户在设置的语言配置中选择个语言设置 像这样 点击添加语言,然后选择一种语言就可以添加进来。 现在就有两种语言,一般的第一的就相当于是你的母语(譬如中文),第二的相当于是你的第二...
  • 一、生成对应语言的文件夹,(下面已增加 中文为例) 1.选中你的工程-&gt;res-&gt;右键 new -&gt; Android resource directory 2.Available qualifiers:选择Locale, 点击 “&gt;&gt;” 按钮 ...
  • android 多语言设置

    2016-06-01 10:02:48
    最近APP里做到了多语言的功能,需要简体中文,繁体中文,英语,三种语言。去查找了一下资料发现语言的切换就只是重载了一下resources; private void setLanguage(int languageType){ Resources resources =...
  • 最近在做一个多语言切换的功能,类似于微信的语言切换,搜了下资料基本上都是以下这种: 1. 实现的效果和微信类似,在设置界面打开切换语言的界面,选择语言后重启 HomeActivity,语言切换完成,下次重新打开 App ...
  • 问题如何在AS上添加多国语言string.xml, 初学者如我,估计也摸不到地方。 bing下网络居然没有找到这个问题的解答,有的是直接在Res下添加语言文件夹即可。这个也是一个方法,但是,我想在AS里直接添加, 所以就折腾...
  • 一、应用对多语言支持的实现 1、所谓的多语言的实现,是指同一个应用界面能支持多种语言的显示,供不同语言的人使用。也就是我们应用内显示的字符串都要有不同语言的多个备份,共系统根据需要调用。 要实现这个功能...
  • 软件一般都会有多语言的适配,安卓中也有多语言配置方案,主要是通过Configuration类中的Locale进行多语言的适配。 1.什么是Locale Locale是JavaSE中一个类,用以表示本地语言的类型,可用于日历、数字和字符串...
  • 前言  近期偶然发现一个问题,我们的应用在7.0以上的个别机型上,会遇到国际...系统语言设置:首选 - 中文简体、次选 - 日语、第三顺位 - 英语 应用支持的资源配置:values - 中文资源、values-en - 英文资源  ...
  • Android 8.0 系统处理多语言切换,当杀掉应用后再次进来时,发现设置的多语言切换无效 设置的简略代码如下 /** * 设置语言 */ public void setConfiguration() { Locale targetLocale = ...
  • Android语言切换原理

    2017-11-19 15:12:55
    Android语言切换原理前言 之前因为系统有些国家使用的字体乱码的原因,研究了下Android系统字体加载相关的知识,写了一篇Android系统字体加载流程的总结,浅析Android字体加载原理,然而系统的字体与系统当前的语言...
  • Ubuntu环境下配置Android Studio   之前学习Android开发的时候,一直跟各种教程一样,使用的是Eclipse+ADT,主要是比较方便,容易上手,特别是对于习惯用Eclipse开发java的朋友来说,上手更是好无压力。但毕竟...
  • 下面用使用android studio演示一遍1.建立文件 额.因为展示的问题,strings都被集合了,怕大家蒙蔽,我展示下实际情况如下:2.添加资源 三个文件夹中含有同样name的string。给大家解释一下这几个的关系: 默认...
1 2 3 4 5 ... 20
收藏数 70,114
精华内容 28,045