Flutter多語言實踐
官方流程
簡單來講,流程圖如下
簡單講一下整個流程
- 我們先寫一個
AppStrings.dart
,這個檔案是整個多語言的核心,生成和使用都需要這個檔案。在這個檔案裡可以定義獲得文字的api,比如
String order_list_waiting_for_review() => Intl.message(
`Waiting for the review`,
name: "order_list_waiting_for_review",
locale: _localeName
);
其中,方法名和name
必須保持一致(不要問我為何會有這種坑爹要求)。`Waiting for the review`
是預設文案,locale
是當前的locale。
這樣定義的話,可以用下面的方式獲得文字
String text = AppStrings.of(context).order_list_waiting_for_review();
// text == "Waiting for the review"
很好理解,AppStrings.of(context)
就是通過context
獲得對應的locale
的AppStrings
,進而獲得對應的文案。
- 在上面以那種格式定義後,我們可以執行下面這個命令把
AppStrings.dart
生成intl_messages.arb
flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/app_strings.dart
*.arb
是個中間產物,其內就是JSON文字。其實會有更多附加資訊,描述這個文字,不過在此省略。
{
"order_list_waiting_for_review": "Waiting for the review",
}
- 生成的
arb
檔案只是一種語言的,我們可以把它拷貝成N種語言對應的檔案,比如intl_en.arb
,intl_es.arb
等,並把內容的value都替換成對應語言的文案。 - 然後再執行下面這個命令,生成
messages_*.dart
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n
--no-use-deferred-loading lib/app_strings.dart lib/l10n/intl_*.arb
可以看到,作為入參的是lib/app_strings.dart
和lib/l10n/intl_*.arb
,flutter工具黨確保lib/app_strings.dart
中的方法名、方法中的name引數,和lib/l10n/intl_*.arb
中的json的key一致的時候,才會在生成的messages_*.dart
檔案中加入對應的文案,缺一不可。
我們再回過頭來看這段程式碼
String order_list_waiting_for_review() => Intl.message(
`Waiting for the review`,
name: "order_list_waiting_for_review",
locale: _localeName
);
Intl.message()
方法實際上是根據locale
獲取對應的message_*.dart
檔案,然後再通過name
找到對應的文案返回。
- 當然,還需要對
MaterialApp
定義localizationsDelegates本地化代理
和supportedLocales支援的多語言
,這部分在文章最開始的文件裡寫的很詳細了,就不再贅述了。
官方方案的問題
官方的方案雖然很長很繁瑣,但還是可以實現多語言的功能的,只是對於我們來講,它存在以下幾個問題:
- 需要在
AppStrings.dart
中定義文字獲得的方法,一個文字就需要定義一個方法,並且方法名和name
必須一致才能和arb
檔案一起生成最後的dart
檔案。一個文案對應一個方法,程式碼寫起來很冗餘,並且不利於文案的列舉使用(比如文案的key之間有關係)。和native開發之前的習慣也不同。使用和生成的邏輯放到一起,倘若有幾千個文案,AppStrings.dart
估計要爆表。 - 流程太長,不利於自動化下載語言的指令碼的實現。
我們的流程
起點的i18n.py是我們自己寫的python指令碼,一共有兩個作用
- 從美杜莎(阿里國際化文案管理平臺)上獲得多語言文案,並重新命名成
arb
檔案。
前面說到,arb檔案其實是json格式的,美杜莎支援以json格式匯出文字,所以我們做的只是重新命名,不需要對內容進行更改。
- 在
arb
檔案處理好後,會拿預設的(英語)文字去生成一個dart檔案,這個dart檔案只用來作為中間產物,不會被其他dart使用的。
其中只包含如下內容
import `package:intl/intl.dart`;
class MessagesIndex {
String order_list_waiting_for_review() => Intl.message(
`Waiting for the review`,
name: "order_list_waiting_for_review",
);
// ......
}
那麼,我們繼續呼叫生成最終產物的命令列
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n
--no-use-deferred-loading lib/messages_index.dart lib/l10n/intl_*.arb
發現檔案以及其內的文案已經被正確生成了。
呼叫方式
我之所以這樣更改流程,其實只有兩個目的:
- 可以像讀map一樣的讀取多語言文案,而不是像呼叫方法那樣去讀取。
- 拉取、生成多語言文案的過程可以自動化。
通過上面一頓操作,生成文案的工作都被自動化搞定了,那我們只需要在AppStrings.dart
中新增一個方法,傳入name,傳出想要的多語言文案即可:
class AppStrings {
final String _localeName;
// ......
static AppStrings of(BuildContext context) {
return Localizations.of<AppStrings>(context, AppStrings);
}
// AppStrings.of(context).str(stringKey)
String str(String name) {
return Intl.message(name, name: name, locale: _localeName);
}
// 重寫操作符,減少程式碼量
// AppStrings.of(context)[stringKey]
operator [](String messageName) => str(messageName);
}
相關文章
- 多語言檢測工具實踐
- 以$t形式使用flutter多語言Flutter
- Go 語言實踐(一)Go
- 企業產品網站多語言支援 - 實踐案例網站
- 雲音樂前端國際化多語言探索實踐前端
- Go 語言 context 包實踐GoContext
- 螞蟻金服SOFAMesh在多語言上的實踐 | CNUTCon 實錄
- 如何封裝一個flutter的多語言plugin封裝FlutterPlugin
- Go 語言 viper 庫上手實踐Go
- GPT大語言模型Alpaca-lora本地化部署實踐【大語言模型實踐一】GPT模型
- so easy 前端實現多語言前端
- .NET CORE 多語言實現方案
- 自然語言處理的最佳實踐自然語言處理
- 9.4語言是一種實踐2
- 使用函式式語言實踐DDD函式
- Flutter實踐Flutter
- C語言實現繼承多型C語言繼承多型
- GO語言泛型程式設計實踐Go泛型程式設計
- Go 語言目錄結構與實踐Go
- 函數語言程式設計最佳實踐函數程式設計
- Linux下跨語言呼叫C++實踐LinuxC++
- flutter【3】dart語言--方法FlutterDart
- Android 實現APP可切換多語言AndroidAPP
- 如何實現 OpenAPI 多語言 SDK 開發?API
- Flutter 最佳實踐Flutter
- Qt 多語言支援QT
- ModStart多語言支援
- 基於jQuery及騰訊NLP AI平臺的Laravel多語言站點實踐jQueryAILaravel
- “踩坑”經驗分享:Swift語言落地實踐Swift
- Flutter系列之Dart語言概述FlutterDart
- C語言實現多級濾波—乾貨C語言
- 前端另一種多語言的實現思路前端
- Android國際化(多語言)實現,支援8.0Android
- 《NLP漢語自然語言處理原理與實踐》學習四自然語言處理
- 【Flutter 1-7】Flutter教程Dart語言——變數FlutterDart變數
- 低程式碼與大語言模型的探索實踐模型
- 函數語言程式設計入門實踐(一)函數程式設計
- Flutter探索與實踐Flutter