<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                借助于 App Store 與 Google Play,我們能夠把應用發布到全世界的任何一個應用商店里。應用的(潛在)使用者可能來自于不同國家、說著不同的語言。如果我們想為全世界的使用者提供統一而標準的體驗,那么首先就需要讓 App 能夠支持多種語言。而這一過程,一般被稱為“國際化”。 提起國際化,你可能會認為這等同于翻譯 App 內所有用戶可見的文本。其實,這個觀點不夠精確。**更為準確地描述國際化的工作職責,應該是“涉及語言及地區差異的適配改造過程”。** 比如,如果我們要顯示金額,同樣的面值,在中國會顯示為¥100,而在美國則會顯示為 $100;又比如,App 的引導圖,在中國我們可能會選用長城作為背景,而在美國我們則可能會選擇金門大橋作為背景。 因此,對一款 App 做國際化的具體過程,除了翻譯文案之外,還需要將貨幣單位和背景圖等資源也設計成可根據不同地區自適應的變量。這也就意味著,我們在設計 App 架構時,需要提前將語言與地區的差異部分獨立出來。 其實,這也是在 Flutter 中進行國際化的整體思路,即語言差異配置抽取 + 國際化代碼生成。而在語言差異配置抽取的過程中,文案、貨幣單位,以及背景圖資源的處理,其實并沒有本質區別。所以在今天的分享中,我會以多語言文案為主,為你講述在 Flutter 中如何實現語言與地區差異的獨立化,相信在學習完這部分的知識之后,對于其他類型的語言差異你也能夠輕松搞定國際化了。 ## Flutter i18n 在 Flutter 中,國際化的語言和地區的差異性配置,是應用程序代碼的一部分。如果要在 Flutter 中實現文本的國際化,我們需要執行以下幾步: * 首先,實現一個 LocalizationsDelegate(即翻譯代理),并將所有需要翻譯的文案全部聲明為它的屬性; * 然后,依次為需要支持的語言地區進行手動翻譯適配; * 最后,在應用程序 MaterialApp 初始化時,將這個代理類設置為應用程序的翻譯回調。 如果我們中途想要新增或者刪除某個語系或者文案,都需要修改程序代碼。 看到這里你會發現,如果我們想要使用官方提供的國際化方案來設計 App 架構,不僅工作量大、繁瑣,而且極易出錯。所以,要開始 Flutter 應用的國際化道路,我們不如把官方的解決方案扔到一邊,直接**從 Android Studio 中的 Flutter i18n 插件開始學習**。這個插件在其內部提供了不同語言地區的配置封裝,能夠幫助我們自動地從翻譯稿生成 Dart 代碼。 為了安裝 Flutter i18n 插件,我們需要打開 Android Studio 的 Preference 選項,在左邊的 tab 中,切換到 Plugins 選項,搜索這個插件,點擊 install 即可。安裝完成之后再重啟 Android Studio,這個插件就可以使用了。 :-: ![](https://img.kancloud.cn/59/67/59676dae6d5f710da6a428eb2d0fd603_2034x1394.png) 圖 1 Flutter i18n 插件安裝 Flutter i18n 依賴 flutter\_localizations 插件包,所以我們還需要在 pubspec.yaml 文件里,聲明對它的依賴,否則程序會報錯: ~~~ dependencies: flutter_localizations: sdk: flutter ~~~ 這時,我們會發現在 res 文件夾下,多了一個 values/strings\_en.arb 的文件。 arb 文件是 JSON 格式的配置,用來存放文案標識符和文案翻譯的鍵值對。所以,我們只要修改了 res/values 下的 arb 文件,i18n 插件就會自動幫我們生成對應的代碼。 strings\_en 文件,則是系統默認的英文資源配置。為了支持中文,我們還需要在 values 目錄下再增加一個 strings\_zh.arb 文件: :-: ![](https://img.kancloud.cn/d3/ac/d3ac46709b5ca24cd193b06def732864_1354x926.png) 圖 2 arb 文件格式 試著修改一下 strings\_zh.arb 文件,可以看到,Flutter i18n 插件為我們自動生成了 generated/i18n.dart。這個類中不僅以資源標識符屬性的方式提供了靜態文案的翻譯映射,對于通過參數來實現動態文案的 message\_tip 標識符,也自動生成了一個同名內聯函數: :-: ![](https://img.kancloud.cn/21/78/2178c10594f5759c8195b19a7c7e00c5_1668x542.png) 圖 3 Flutter i18n 插件自動生成代碼 我們把 strings\_en.arb 繼續補全,提供英文版的文案。需要注意的是,i18n.dart 是由插件自動生成的,每次 arb 文件有新的變更都會自動更新,所以切忌手動編輯這個文件。 接下來,我們**以 Flutter 官方的工程模板,即計數器 demo 來演示如何在 Flutter 中實現國際化**。 在下面的代碼中,我們在應用程序的入口,即 MaterialApp 初始化時,為其設置了支持國際化的兩個重要參數,即 localizationsDelegates 與 supportedLocales。前者為應用的翻譯回調,而后者則為應用所支持的語言地區屬性。 S.delegate 是 Flutter i18n 插件自動生成的類,包含了所支持的語言地區屬性,以及對應的文案翻譯映射。理論上,通過這個類就可以完全實現應用的國際化,但為什么我們在配置應用程序的翻譯回調時,除了它之外,還加入了 GlobalMaterialLocalizations.delegate 與 GlobalWidgetsLocalizations.delegate 這兩個回調呢? 這是因為 Flutter 提供的 Widget,其本身已經支持了國際化,所以我們沒必要再翻譯一遍,直接用官方的就可以了,而這兩個類則就是官方所提供的翻譯回調。事實上,我們剛才在 pubspec.yaml 文件中聲明的 flutter\_localizations 插件包,就是 Flutter 提供的翻譯套裝,而這兩個類就是套裝中的著名成員。 在完成了應用程序的國際化配置之后,我們就可以在程序中通過 S.of(context),直接獲取 arb 文件中翻譯的文案了。 不過需要注意的是,**提取翻譯文案的代碼需要在能獲取到翻譯上下文的前提下才能生效,也就是說只能針對 MaterialApp 的子 Widget 生效。**因此,在這種配置方式下,我們是無法對 MaterialApp 的 title 屬性進行國際化配置的。不過,好在 MaterialApp 提供了一個回調方法 onGenerateTitle,來提供翻譯上下文,因此我們可以通過它,實現 title 文案的國際化: ~~~ // 應用程序入口 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: const [ S.delegate,// 應用程序的翻譯回調 GlobalMaterialLocalizations.delegate,//Material 組件的翻譯回調 GlobalWidgetsLocalizations.delegate,// 普通 Widget 的翻譯回調 ], supportedLocales: S.delegate.supportedLocales,// 支持語系 //title 的國際化回調 onGenerateTitle: (context){ return S.of(context).app_title; }, home: MyHomePage(), ); } } ~~~ 應用的主界面文案的國際化,則相對簡單得多了,直接通過 S.of(context) 方法就可以拿到 arb 聲明的翻譯文案了: ~~~ Widget build(BuildContext context) { return Scaffold( // 獲取 appBar title 的翻譯文案 appBar: AppBar( title: Text(S.of(context).main_title), ), body: Center( // 傳入 _counter 參數,獲取計數器動態文案 child: Text( S.of(context).message_tip(_counter.toString()) ) ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter,// 點擊回調 tooltip: 'Increment', child: Icon(Icons.add), ), ); } ~~~ 在 Android 手機上,分別切換英文和中文系統,可以看到,計數器應用已經正確地處理了多語言的情況。 :-: ![](https://img.kancloud.cn/5f/35/5f352551211ae6e063b8561ce02254ab_616x1280.gif) 圖 4 計數器示例(Android 英文系統) :-: ![](https://img.kancloud.cn/f3/b2/f3b249143095cf4210183f995f71f6e0_616x1280.gif) 圖 5 計數器示例(Android 中文系統) 由于 iOS 應用程序有一套自建的語言環境管理機制,默認是英文。為了讓 iOS 應用正確地支持國際化,我們還需要在原生的 iOS 工程中進行額外的配置。我們打開 iOS 原生工程,切換到工程面板。在 Localization 這一項配置中,我們看到 iOS 工程已經默認支持了英文,所以還需要點擊“+”按鈕,新增中文: :-: ![](https://img.kancloud.cn/06/88/0688c4a91a4606eec5ca3d14f170cf14_1900x956.png) 圖 6 iOS 工程中文配置 完成 iOS 的工程配置后,我們回到 Flutter 工程,選擇 iOS 手機運行程序。可以看到,計數器的 iOS 版本也可以正確地支持國際化了。 :-: ![](https://img.kancloud.cn/6c/ba/6cbacb27d1b8009b982e6a2468f79111_448x960.gif) 圖 7 計數器示例(iOS 英文系統) :-: ![](https://img.kancloud.cn/83/c9/83c948476dabc20c23cf06d6220721d8_448x960.gif) 圖 8 計數器示例(iOS 中文系統) ## 原生工程配置 上面介紹的國際化方案,其實都是在 Flutter 應用內實現的。而在 Flutter 框架運行之前,我們是無法訪問這些國際化文案的。 Flutter 需要原生環境才能運行,但有些文案,比如應用的名稱,我們需要在 Flutter 框架運行之前就為它提供多個語言版本(比如英文版本為 computer,中文版本為計數器),這時就需要在對應的原生工程中完成相應的國際化配置了。 **我們先去 Android 工程下進行應用名稱的配置。** 首先,在 Android 工程中,應用名稱是在 AndroidManifest.xml 文件中 application 的 android:label 屬性聲明的,所以我們需要將其修改為字符串資源中的一個引用,讓其能夠根據語言地區自動選擇合適的文案: ~~~ <manifest ... > ... <!-- 設置應用名稱 --> <application ... android:label="@string/title" ... > </application> </manifest> ~~~ 然后,我們還需要在 android/app/src/main/res 文件夾中,為要支持的語言創建字符串 strings.xml 文件。這里由于默認文件是英文的,所以我們只需要為中文創建一個文件即可。字符串資源的文件目錄結構,如下圖所示: :-: ![](https://img.kancloud.cn/95/9e/959ec47a7916cc6f1b44817bd5ddaaff_366x496.png) 圖 9 strings.xml 文件目錄結構 values 與 values-zh 文件夾下的 strings.xml 內容如下所示: ~~~ <!-- 英文 (默認) 字符串資源 --> <?xml version="1.0" encoding="utf-8"?> <resources> <string name="title">Computer</string> </resources> <!-- 中文字符串資源 --> <?xml version="1.0" encoding="utf-8"?> <resources> <string name="title"> 計數器 </string> </resources> ~~~ 完成 Android 應用標題的工程配置后,我們回到 Flutter 工程,選擇 Android 手機運行程序,可以看到,計數器的 Android 應用標題也可以正確地支持國際化了。 接下來,我們再看**iOS 工程下如何實現應用名稱的配置**。 與 Android 工程類似,iOS 工程中的應用名稱是在 Info.list 文件的 Bundle name 屬性聲明的,所以我們也需要將其修改為字符串資源中的一個引用,使其能夠根據語言地區自動選擇文案: :-: ![](https://img.kancloud.cn/1d/4a/1d4a885a83c2297d1c8d1fe6118e46eb_1950x986.png) 圖 10 iOS 工程應用名稱配置 由于應用名稱默認是不可配置的,所以工程并沒有提供英文或者中文的可配置項,這些都需要通過新建與字符串引用對應的資源文件去搞定的。 我們右鍵單擊 Runner 文件夾,然后選擇 New File 來添加名為 InfoPlist.strings 的字符串資源文件,并在工程面板的最右側文件檢查器中的 Localization 選項中,添加英文和中文兩種語言。InfoPlist.strings 的英文版和中文版內容如下所示: ~~~ // 英文版 "CFBundleName" = "Computer"; // 中文版 "CFBundleName" = " 計數器 "; ~~~ 至此,我們也完成了 iOS 應用標題的工程配置。我們回到 Flutter 工程,選擇 iOS 手機運行程序,發現計數器的 iOS 應用標題也支持國際化了。 ## 總結 好了,今天的分享就到這里。我們來總結下核心知識點吧。 在今天的分享中,我與你介紹了 Flutter 應用國際化的解決方案,即在代碼中實現一個 LocalizationsDelegate,在這個類中將所有需要翻譯的文案全部聲明為它的屬性,然后依次進行手動翻譯適配,最后將這個代理類設置為應用程序的翻譯回調。 而為了簡化手動翻譯到代碼轉換的過程,我們通常會使用多個 arb 文件存儲文案在不同語言地區的映射關系,并使用 Flutter i18n 插件來實現代碼的自動轉換。 國際化的核心就是語言差異配置抽取。在原生 Android 和 iOS 系統中進行國際化適配,我們只需為需要國際化的資源(比如,字符串文本、圖片、布局等)提供不同的文件夾目錄,就可以在應用層代碼訪問國際化資源時,自動根據語言地區進行適配。 但,Flutter 的國際化能力就相對原始很多,不同語言和地區的國際化資源既沒有存放在單獨的 xml 或者 JSON 上,也沒有存放在不同的語言和地區文件夾中。幸好有 Flutter i18n 插件的幫助,否則為一個應用提供國際化的支持將會是件極其繁瑣的事情。 我把今天分享所涉及到的知識點打包到了[GitHub](https://github.com/cyndibaby905/32_i18n_demo)中,你可以下載下來,反復運行幾次,加深理解與記憶。 ## 思考題 最后,我給你留下一道思考題吧。 在 Flutter 中,如何實現圖片類資源的國際化呢?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看