App內切換語言

来源:http://www.cnblogs.com/cnwutianhao/archive/2017/04/22/6746981.html
-Advertisement-
Play Games

轉載請註明出處 http://www.cnblogs.com/cnwutianhao/p/6746981.html 前幾天客戶提需求,對App增加一個功能,這個功能目前市面上已經很常見,那就是應用內切換語言。啥意思,就是 英、中、法、德、日。。。語言隨意切換。 (本案例採用Data-Bingding ...


轉載請註明出處 http://www.cnblogs.com/cnwutianhao/p/6746981.html 

 

前幾天客戶提需求,對App增加一個功能,這個功能目前市面上已經很常見,那就是應用內切換語言。啥意思,就是 英、中、法、德、日。。。語言隨意切換。

(本案例採用Data-Bingding模式,麻麻再也不用擔心我findViewBy不到Id了哈哈,開個玩笑)

先上示例圖:

 

代碼實現:

佈局文件(Data-Binding模式),很簡單就是兩行文字

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.tnnowu.android.switchlanguage.MainActivity">

        <TextView
            android:id="@+id/titleTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="@string/title"
            android:textSize="30sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/descTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/titleTextView"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:text="@string/desc"
            android:textSize="20sp" />

    </RelativeLayout>

</layout>

 

從實例中我們可以看到右上角是有Menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/language_english"
        android:orderInCategory="100"
        android:title="@string/menu_english" />
    <item
        android:id="@+id/language_simplified_chinese"
        android:orderInCategory="100"
        android:title="@string/menu_simplified_chinese" />
    <item
        android:id="@+id/language_turkish"
        android:orderInCategory="100"
        android:title="@string/menu_turkish" />
    <item
        android:id="@+id/language_japanese"
        android:orderInCategory="100"
        android:title="@string/menu_japanese" />

</menu>

(既然是多語言,所以就要有N個strings)

,本案例我創建了4種語言。

 

好的,Menu的佈局寫完了,接下來就是實現Menu功能,記住實現Menu就兩套代碼,一個 onCreateOptionsMenu , 另一個是 onOptionsItemSelected 。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.language_english) {
        updateViews("en");
    } else if (id == R.id.language_simplified_chinese) {
        updateViews("zh");
    } else if (id == R.id.language_turkish) {
        updateViews("tr");
    } else if (id == R.id.language_japanese) {
        updateViews("ja");
    }
    return super.onOptionsItemSelected(item);
}

 

在這裡,可以看到,我們自定義一個 updateViews() 方法,用來實現切換預言時界面的改變

private void updateViews(String languageCode) {
    Context context = LocaleHelper.setLocale(this, languageCode);
    Resources resources = context.getResources();

    mBinding.titleTextView.setText(resources.getString(R.string.title));
    mBinding.descTextView.setText(resources.getString(R.string.desc));

    setTitle(resources.getString(R.string.toolbar_title));
}

 

公佈一個 語言判斷的類 LocaleHelper

public class LocaleHelper {

    private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";

    public static Context onAttach(Context context) {
        String lang = getPersistedData(context, Locale.getDefault().getLanguage());
        return setLocale(context, lang);
    }

    public static Context onAttach(Context context, String defaultLanguage) {
        String lang = getPersistedData(context, defaultLanguage);
        return setLocale(context, lang);
    }

    public static String getLanguage(Context context) {
        return getPersistedData(context, Locale.getDefault().getLanguage());
    }

    public static Context setLocale(Context context, String language) {
        persist(context, language);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        }

        return updateResourcesLegacy(context, language);
    }

    private static String getPersistedData(Context context, String defaultLanguage) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
    }

    private static void persist(Context context, String language) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();

        editor.putString(SELECTED_LANGUAGE, language);
        editor.apply();
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        Resources resources = context.getResources();

        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }
}

 

最後還要做的操作就是,自定義一個Application類,用來設定App的預設語言(當然了,要將這個Application應用到Manifest中)

public class BaseApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
    }

}

 

本案例實現App內語言切換代碼量不大,通俗易懂,無垃圾代碼。

示例代碼下載地址:App內切換語言

 

關註我的新浪微博,請認準黃V認證,獲取最新安卓開發資訊。

關註科技評論家,領略科技、創新、教育以及最大化人類智慧與想象力!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天學習了一個瀑布流載入效果,很多網站都有瀑布流效果,瀑布流就是很多產品顯示在網頁上,寬相同,高度不同,表現為多欄佈局,隨著頁面滾動條向下滾動,這種佈局還會不斷載入數據塊並附加至當前尾部。原理是:1.設定一行中的列數;2.取第一行中每一個div的高度並把每一個高度放進一個數組中;3.算出數組中最小高 ...
  • Vysor是一款非常強大而有好用的Android遠程顯示及控制軟體,有Chrome插件版、Windows客戶端版和Mac版,是Android開發和測試人員的必備神器。其中Windows客戶端版相對Chrome插件版更為穩定可靠。Chrome插件版經常會出現連接上以後黑屏、閃屏或彈出各種異常提示的問題 ...
  • 這一次是針對Android開發中的一個小問題,許可權獲取的問題。 ...
  • 原作者再舉一例子,說明在Kotlin中怎使用Java使用過的相同庫:Retrofit。 ...
  • 這次給大家介紹兩個比較好用的提示插件,如成功、等待、錯誤提示。 準備: 1、新建一個Prism Xamarin.Forms項目; 2、右擊解決方案,添加NuGet包: 1)Acr.UserDialogs(全部安裝); 2)AndHUD(安卓項目安裝),BTProgressHUD(iOS項目安裝); ...
  • 項目開發中在所難免的要對獲取到的數據進行模型嵌套分析,一層兩層還好,但是多了,對於一些初學者,就會很頭疼。 今天我們說一下如何利用 YYModel 來解析嵌套模型,以省市區為例: 1.先對模型嵌套分析: 假設我們最初拿到的數據是一個裝著省模型(provinceModel)的字典數組,裡面有:省名字 ...
  • 談到設置圓角頭像的問題,我想大多數人第一反應想到的是設置圖像的 layer let imageV: UIImageView = UIImageView() imageV.layer.cornerRadius = 26 imageV.layer.masksToBounds = true 這是一種方式, ...
  • 最近在Android和IOS上都需要對用戶的某些輸入進行簡單的加密,於是採用MD5加密方式。 首先將目的字元串加密一次,獲得32位字元串 然後將32位字元串拆為2段,分別加密1次 最後將加密後的2段拼接,加密100次 下麵是Android的Java部分和IOS的Objective C部分 impor ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...