Flutter配置多語言络凿,國際化之后的優(yōu)化

Flutter配置國際化骡送,多語言步驟優(yōu)化


請(qǐng)先參考國際化 · 《Flutter實(shí)戰(zhàn)》中的intl章節(jié)完成國際化配置至能夠使用


其中intl.sh文件的部分注釋

# lib/i10n/localization_intl.dart 要進(jìn)行翻譯的(其中包含有Intl相關(guān)方法)文件
# i10n-arb/intl_*.arb 轉(zhuǎn)換后的.arb文件 2
# i10n-arb 存放1轉(zhuǎn)換后的相應(yīng).arb文件的目錄 3
# lib/i10n 存放2再轉(zhuǎn)換成相應(yīng)dart文件的目錄 4

# 轉(zhuǎn)換成arb。傳入3和1
flutter pub pub run intl_translation:extract_to_arb --output-dir=i10n-arb lib/i10n/localization_intl.dart
# 將arb轉(zhuǎn)化成相關(guān)dart文件喷众。傳入4,1和2
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i10n --no-use-deferred-loading lib/i10n/localization_intl.dart i10n-arb/intl_*.arb

1. 抽離要翻譯字段

  • 刪除掉lib/i10n/localization_intl.dart中以下部分
String get title {
  return Intl.message(
    'Flutter APP',
    name: 'title',
    desc: 'Title for the Demo application',
  );
}
  • 新建lib/i10n/mixins文件夾

  • mixins文件夾中新建commom.dart文件并寫入

// ignore_for_file: non_constant_identifier_names
import 'package:intl/intl.dart';

mixin Commom {
  // 加上前綴方便在.arb文件中區(qū)分
  String get commom_title => Intl.message(
        'Flutter APP',
        name: 'commom_title', // 在.arb文件中顯示的字段名
        desc: 'Title for the Demo application');
}
  • lib/i10n/localization_intl.dart引用
// ...
import './mixins/commom.dart';
// ...
class DemoLocalizations with Common {
// ...

  • 修改intl.sh文件
    • 只修改了1相應(yīng)的路徑
# lib/i10n/mixins/** 要進(jìn)行翻譯的(其中包含有Intl相關(guān)方法)文件 1
# i10n-arb/intl_*.arb 轉(zhuǎn)換后的.arb文件 2
# i10n-arb 存放1轉(zhuǎn)換后的相應(yīng).arb文件的目錄 3
# lib/i10n 存放2再轉(zhuǎn)換成相應(yīng)dart文件的目錄 4

# 轉(zhuǎn)換成arb各谚。傳入3和1
flutter pub pub run intl_translation:extract_to_arb --output-dir=i10n-arb lib/i10n/mixins/**
# 將arb轉(zhuǎn)化成相關(guān)dart文件。傳入4,1和2
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i10n --no-use-deferred-loading lib/i10n/mixins/** i10n-arb/intl_*.arb
  • 完成

2. 簡化翻譯步驟(需要安裝Node.js)

參考使用Intl包 · 《Flutter實(shí)戰(zhàn)》當(dāng)前的翻譯步驟為

  • lib/i10n/mixins/下相關(guān)文件添加要翻譯的字段
  • 執(zhí)行./intl.sh
  • i10n-arb/下相關(guān)文件進(jìn)行相應(yīng)的翻譯
  • 執(zhí)行./intl.sh

缺點(diǎn)

  • 需要在多處相關(guān)文件進(jìn)行相關(guān)改動(dòng)
  • 翻譯時(shí)的.arb文件需要和i10n-arb/intl_messages.arb進(jìn)行對(duì)比到千,并進(jìn)行手動(dòng)更改
  • 若是修改之前的翻譯字段昌渤,可能需要對(duì)部分.arb文件進(jìn)行相關(guān)的手動(dòng)修改
  • 需要多次執(zhí)行./intl.sh

優(yōu)化思路

  • 原步驟中第一次執(zhí)行./intl.sh是為了執(zhí)行其中第一條命令。
  • 第二次執(zhí)行./intl.sh是為了執(zhí)行其中第二條命令憔四。
  • 因此只要將對(duì).arb文件進(jìn)行相關(guān)翻譯通過命令行執(zhí)行即可

優(yōu)化后的步驟

  • lib/i10n/mixins/下相關(guān)文件添加要翻譯的字段
  • 執(zhí)行./intl.sh

如何優(yōu)化

  • 根目錄下添加node_intl.js文件
const fs = require("fs");
const path = require("path");
// 要轉(zhuǎn)換的語言(默認(rèn)語言不填)
const localeList = ["en", "ja"];
// 獲取命令行參數(shù)
const params = process.argv.splice(2);

// 判斷是否為Object-JSON格式
function canParse(str) {
  try {
    return (
      str !== "" &&
      typeof str == "string" &&
      Object.prototype.toString.call(JSON.parse(str)) === "[object Object]"
    );
  } catch (error) {
    return false;
  }
}
// 對(duì)文件 根據(jù)locale 進(jìn)行修改
// locale = "en";
// 原來:
// "commom_tab_home": "首頁",
// "@commom_tab_home": {
//   "description": "{\"desc\":\"底部tab中的首頁\",\"en\":\"Home\"}",
//   "type": "text",
//   "placeholders": {}
// },
// 修改后:
// "commom_tab_home": "Home",
// "@commom_tab_home": {
//   "description": "{\"desc\":\"底部tab中的首頁\",\"en\":\"Home\"}",
//   "type": "text",
//   "placeholders": {}
// },
function translateAccordingToLocale(fileContent) {
  const newFileContentObj = {};
  // 復(fù)制原文件內(nèi)容膀息,僅修改locale
  localeList.forEach((locale) => {
    let data = JSON.parse(fileContent);
    data["@@locale"] = locale;
    newFileContentObj[locale] = data;
  });

  // 遍歷原文件內(nèi)容,根據(jù)description進(jìn)行相應(yīng)轉(zhuǎn)換
  const data = JSON.parse(fileContent);
  for (const key in data) {
    if (data.hasOwnProperty(key) && /^@[^@]/.test(key)) {
      const element = data[key]["description"];
      if (canParse(element)) {
        const desc = JSON.parse(element);
        // 根據(jù)description進(jìn)行相應(yīng)轉(zhuǎn)換
        localeList.forEach((locale) => {
          const translateToLocale = desc[locale];
          translateToLocale &&
            (newFileContentObj[locale][
              key.replace(/^@/, "")
            ] = translateToLocale);
        });
      }
    }
  }

  return Promise.resolve(newFileContentObj);
}

// 寫入arb文件
function writeArb(fileContentObj) {
  return new Promise((resolve, reject) => {
    for (const locale in fileContentObj) {
      if (fileContentObj.hasOwnProperty(locale)) {
        fs.writeFile(
          path.join(__dirname, `${params[0]}/intl_${locale}.arb`),
          // 寫入格式化后的文件內(nèi)容
          JSON.stringify(fileContentObj[locale], null, 2),
          (err) => err && reject(err)
        );
      }
    }
  });
}

// 讀取源arb文件
function readArb() {
  return new Promise((resolve, reject) => {
    if (params.length == 0) return reject("請(qǐng)傳入相關(guān).arb文件所在目錄");
    fs.readFile(
      path.join(__dirname, `${params[0]}/intl_messages.arb`),
      (err, data) => (err ? reject(err) : resolve(data))
    );
  });
}

readArb()
  .then(translateAccordingToLocale)
  .then(writeArb)
  .catch((e) => {
    console.error(`Node_Intl Error: ${e}`);
  });

  • 修改./intl.sh文件
    • 原來兩條命令中新增一條命令
# lib/i10n/mixins/** 要進(jìn)行翻譯的(其中包含有Intl相關(guān)方法)文件 1
# i10n-arb/intl_*.arb 轉(zhuǎn)換后的.arb文件 2
# i10n-arb 存放1轉(zhuǎn)換后的相應(yīng).arb文件的目錄 3
# lib/i10n 存放2再轉(zhuǎn)換成相應(yīng)dart文件的目錄 4

# 轉(zhuǎn)換成arb了赵。傳入3和1
flutter pub pub run intl_translation:extract_to_arb --output-dir=i10n-arb lib/i10n/mixins/**
# 優(yōu)化翻譯步驟 傳入3
node node_intl.js i10n-arb
# 將arb轉(zhuǎn)化成相關(guān)dart文件潜支。傳入4,1和2
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i10n --no-use-deferred-loading lib/i10n/mixins/** i10n-arb/intl_*.arb
  • 翻譯格式
    • lib/i10n/mixins/commom.dart
    • desc格式需要為Object-JSON格式
// ignore_for_file: non_constant_identifier_names
import 'package:intl/intl.dart';

mixin Commom {
  // 加上前綴方便在.arb文件中區(qū)分
  String get commom_title => Intl.message(
        'Flutter APP',
        name: 'commom_title', // 在.arb文件中顯示的字段名
        desc: '{"desc":"Title for the Demo application","en":"英文翻譯在這","ja":"日語翻譯在這"}');
}
  • 完成
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市柿汛,隨后出現(xiàn)的幾起案子冗酿,更是在濱河造成了極大的恐慌,老刑警劉巖络断,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裁替,死亡現(xiàn)場離奇詭異,居然都是意外死亡貌笨,警方通過查閱死者的電腦和手機(jī)弱判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锥惋,“玉大人昌腰,你說我怎么就攤上這事“虻” “怎么了遭商?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捅伤。 經(jīng)常有香客問我株婴,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任困介,我火速辦了婚禮,結(jié)果婚禮上蘸际,老公的妹妹穿的比我還像新娘座哩。我一直安慰自己,他們只是感情好粮彤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布根穷。 她就那樣靜靜地躺著,像睡著了一般导坟。 火紅的嫁衣襯著肌膚如雪屿良。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天惫周,我揣著相機(jī)與錄音尘惧,去河邊找鬼。 笑死递递,一個(gè)胖子當(dāng)著我的面吹牛喷橙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播登舞,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贰逾,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了菠秒?” 一聲冷哼從身側(cè)響起疙剑,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎践叠,沒想到半個(gè)月后言缤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酵熙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年轧简,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匾二。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡哮独,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出察藐,到底是詐尸還是另有隱情皮璧,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布分飞,位于F島的核電站悴务,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜讯檐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一羡疗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧别洪,春花似錦叨恨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痢毒,卻和暖如春送矩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哪替。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工栋荸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人夷家。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓蒸其,卻偏偏與公主長得像,于是被迫代替她去往敵國和親库快。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摸袁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355