欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现应用内置语言切换功能

程序员文章站 2023-12-19 09:21:58
一、需求 有时候应用需要在内部切换语言但又不影响系统的语言,比如是应用现在是中文的,系统语言也是中文的,我把应用的切换成英文显示后系统语言还是中文的,系统语言切换后也...

一、需求

有时候应用需要在内部切换语言但又不影响系统的语言,比如是应用现在是中文的,系统语言也是中文的,我把应用的切换成英文显示后系统语言还是中文的,系统语言切换后也不会被改变,还有就是有些机的系统是被改造精简过的,比如有些国产机的系统的语言就被精简剩中文和英文。支付宝、微信、top story都有在应用内部设置语言切换这样的功能。

Android实现应用内置语言切换功能

二、实现效果

先看看实现效果吧。

Android实现应用内置语言切换功能

三、实现

(一)添加多种语言的资源文件夹及文件

我这默认是英语再添加了个俄文(google翻译的)和中文。

Android实现应用内置语言切换功能

values/strings.xml

<resources> 
  <string name="app_name">switchlanguage</string> 
  <string name="helloworld">hello world!</string> 
  <string name="language">eng</string> 
  <string name="english">english</string> 
  <string name="chinese">中文</string> 
  <string name="russian">русский</string> 
  <string name="secondact">second activity</string> 
</resources> 

values-ru/strings.xml

<resources> 
  <string name="app_name">переключение язык</string> 
  <string name="helloworld">привет мир!</string> 
  <string name="language">русский</string> 
  <string name="secondact">второй активность</string> 
</resources> 

values-zh/strings.xml

<resources> 
  <string name="app_name">切换语言</string> 
  <string name="helloworld">你好 世界!</string> 
  <string name="language">中文</string> 
  <string name="secondact">第二屏</string> 
</resources> 

(二)布局文件
activity_main.xml

默认标题栏的文字是切换语言后是不会被改变的,使用toobar替换掉就可以了。

<?xml version="1.0" encoding="utf-8"?> 
<linearlayout 
  android:id="@+id/activity_main" 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical" 
  tools:context="com.ce.switchlanguage.mainactivity" 
  xmlns:app="http://schemas.android.com/apk/res-auto"> 
  <android.support.design.widget.appbarlayout 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:theme="@style/apptheme.appbaroverlay"> 
 
    <android.support.v7.widget.toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionbarsize" 
      android:background="?attr/colorprimary" 
      app:popuptheme="@style/apptheme.popupoverlay" 
      app:title="@string/app_name"/> 
 
  </android.support.design.widget.appbarlayout> 
  <textview 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/helloworld"/> 
  <button 
    android:id="@+id/change" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:text="@string/language"/> 
</linearlayout> 

styles.xml

设置语言后需要重启下activity,启动会有个效果,使用windowdisablepreview屏蔽掉它。

<resources> 
  <style name="apptheme" parent="theme.appcompat.light.darkactionbar"> 
    <item name="colorprimary">@color/colorprimary</item> 
    <item name="colorprimarydark">@color/colorprimarydark</item> 
    <item name="coloraccent">@color/coloraccent</item> 
    <item name="windowactionbar">false</item> 
    <item name="windownotitle">true</item> 
    <item name="android:windowdisablepreview">true</item> 
  </style> 
  <style name="apptheme.appbaroverlay" parent="themeoverlay.appcompat.dark.actionbar"/> 
  <style name="apptheme.popupoverlay" parent="themeoverlay.appcompat.dark"/> 
</resources> 

main_menu.xml

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto"> 
  <item android:id="@+id/chinese" android:title="@string/chinese" app:showasaction="never" /> 
  <item android:id="@+id/english" android:title="@string/english" app:showasaction="never" /> 
  <item android:id="@+id/russian" android:title="@string/russian" app:showasaction="never" /> 
</menu> 

(三)localeutils

package com.ce.switchlanguage; 
 
import android.content.context; 
import android.content.sharedpreferences; 
import android.content.res.configuration; 
import android.os.build; 
import android.util.displaymetrics; 
 
import com.google.gson.gson; 
 
import java.util.locale; 
 
public class localeutils { 
  /** 
   * 中文 
   */ 
  public static final locale locale_chinese = locale.chinese; 
  /** 
   * 英文 
   */ 
  public static final locale locale_english = locale.english; 
  /** 
   * 俄文 
   */ 
  public static final locale locale_russian = new locale("ru"); 
  /** 
   * 保存sharedpreferences的文件名 
   */ 
  private static final string locale_file = "locale_file"; 
  /** 
   * 保存locale的key 
   */ 
  private static final string locale_key = "locale_key"; 
 
  /** 
   * 获取用户设置的locale 
   * @param pcontext context 
   * @return locale 
   */ 
  public static locale getuserlocale(context pcontext) { 
    sharedpreferences _splocale = pcontext.getsharedpreferences(locale_file, context.mode_private); 
    string _localejson = _splocale.getstring(locale_key, ""); 
    return jsontolocale(_localejson); 
  } 
  /** 
   * 获取当前的locale 
   * @param pcontext context 
   * @return locale 
   */ 
  public static locale getcurrentlocale(context pcontext) { 
    locale _locale; 
    if (build.version.sdk_int >= build.version_codes.n) { //7.0有多语言设置获取顶部的语言 
      _locale = pcontext.getresources().getconfiguration().getlocales().get(0); 
    } else { 
      _locale = pcontext.getresources().getconfiguration().locale; 
    } 
    return _locale; 
  } 
  /** 
   * 保存用户设置的locale 
   * @param pcontext context 
   * @param puserlocale locale 
   */ 
  public static void saveuserlocale(context pcontext, locale puserlocale) { 
    sharedpreferences _splocal=pcontext.getsharedpreferences(locale_file, context.mode_private); 
    sharedpreferences.editor _edit=_splocal.edit(); 
    string _localejson = localetojson(puserlocale); 
    _edit.putstring(locale_key, _localejson); 
    _edit.apply(); 
  } 
  /** 
   * locale转成json 
   * @param puserlocale userlocale 
   * @return json string 
   */ 
  private static string localetojson(locale puserlocale) { 
    gson _gson = new gson(); 
    return _gson.tojson(puserlocale); 
  } 
  /** 
   * json转成locale 
   * @param plocalejson localejson 
   * @return locale 
   */ 
  private static locale jsontolocale(string plocalejson) { 
    gson _gson = new gson(); 
    return _gson.fromjson(plocalejson, locale.class); 
  } 
  /** 
   * 更新locale 
   * @param pcontext context 
   * @param pnewuserlocale new user locale 
   */ 
  public static void updatelocale(context pcontext, locale pnewuserlocale) { 
    if (needupdatelocale(pcontext, pnewuserlocale)) { 
      configuration _configuration = pcontext.getresources().getconfiguration(); 
      if (build.version.sdk_int >= build.version_codes.jelly_bean_mr1) { 
        _configuration.setlocale(pnewuserlocale); 
      } else { 
        _configuration.locale =pnewuserlocale; 
      } 
      displaymetrics _displaymetrics = pcontext.getresources().getdisplaymetrics(); 
      pcontext.getresources().updateconfiguration(_configuration, _displaymetrics); 
      saveuserlocale(pcontext, pnewuserlocale); 
    } 
  } 
  /** 
   * 判断需不需要更新 
   * @param pcontext context 
   * @param pnewuserlocale new user locale 
   * @return true / false 
   */ 
  public static boolean needupdatelocale(context pcontext, locale pnewuserlocale) { 
    return pnewuserlocale != null && !getcurrentlocale(pcontext).equals(pnewuserlocale); 
  } 
} 

locale工具类,这里我用sharedpreferences来保存所设置的locale,locale是实现了serializable的。

(四)activity

package com.ce.switchlanguage; 
 
import android.content.intent; 
import android.os.bundle; 
import android.support.v7.app.appcompatactivity; 
import android.support.v7.widget.toolbar; 
import android.view.menu; 
import android.view.menuitem; 
 
public class mainactivity extends appcompatactivity { 
 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.activity_main); 
    toolbar _toolbar =(toolbar) findviewbyid(r.id.toolbar); 
    setsupportactionbar(_toolbar); 
  } 
 
  @override 
  public boolean oncreateoptionsmenu(menu menu) { 
    getmenuinflater().inflate(r.menu.main_menu,menu); 
    return true; 
  } 
 
  @override 
  public boolean onoptionsitemselected(menuitem item) { 
    int _itemid=item.getitemid(); 
    switch (_itemid) { 
      case r.id.chinese: 
        if (localeutils.needupdatelocale(this, localeutils.locale_chinese)) { 
          localeutils.updatelocale(this, localeutils.locale_chinese); 
          restartact(); 
        } 
        break; 
      case r.id.english: 
        if (localeutils.needupdatelocale(this, localeutils.locale_english)) { 
          localeutils.updatelocale(this, localeutils.locale_english); 
          restartact(); 
        } 
        break; 
      case r.id.russian: 
        if (localeutils.needupdatelocale(this, localeutils.locale_russian)) { 
          localeutils.updatelocale(this, localeutils.locale_russian); 
          restartact(); 
        } 
    } 
    return true; 
  } 
 
  /** 
   * 重启当前activity 
   */ 
  private void restartact() { 
    finish(); 
    intent _intent = new intent(this, mainactivity.class); 
    startactivity(_intent); 
    //清除activity退出和进入的动画 
    overridependingtransition(0, 0); 
  } 
} 

这里只有一个activity所以切换的时候重启下当前activity就好了,栈里还有其他activity的自己再处理吧。

(五)application

package com.ce.switchlanguage; 
 
import android.app.application; 
import android.content.res.configuration; 
import android.os.build; 
 
import java.util.locale; 
 
public class myapplication extends application { 
  @override 
  public void oncreate() { 
    super.oncreate(); 
    locale _userlocale=localeutils.getuserlocale(this); 
    localeutils.updatelocale(this, _userlocale); 
  } 
 
  @override 
  public void onconfigurationchanged(configuration newconfig) { 
    super.onconfigurationchanged(newconfig); 
    locale _userlocale=localeutils.getuserlocale(this); 
    //系统语言改变了应用保持之前设置的语言 
    if (_userlocale != null) { 
      locale.setdefault(_userlocale); 
      configuration _configuration = new configuration(newconfig); 
      if (build.version.sdk_int >= build.version_codes.jelly_bean_mr1) { 
        _configuration.setlocale(_userlocale); 
      } else { 
        _configuration.locale =_userlocale; 
      } 
      getresources().updateconfiguration(_configuration, getresources().getdisplaymetrics()); 
    } 
  } 
} 

在application oncreate的时候更新下,在系统语言改变的时候也要保持之前设置的语言不变。

源码地址:android应用内置语言切换

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: