localization_service.dart 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. // import 'package:google_fonts/google_fonts.dart';
  4. import '../../app/data/sp/ix_sp.dart';
  5. import 'ar_AR/ar_ar_translation.dart';
  6. import 'en_US/en_us_translation.dart';
  7. import 'es_ES/es_es_translation.dart';
  8. import 'my_MM/my_mm_translation.dart';
  9. import 'fa_IR/fa_ir_translation.dart';
  10. import 'de_DE/de_de_translation.dart';
  11. import 'ja_JP/ja_jp_translation.dart';
  12. import 'fr_FR/fr_fr_translation.dart';
  13. import 'ru_RU/ru_ru_translation.dart';
  14. import 'ko_KR/ko_kr_translation.dart';
  15. import 'zh_TW/zh_tw_translation.dart';
  16. import 'zh_CN/zh_cn_translation.dart';
  17. import 'tk_TM/tk_tm_translation.dart';
  18. import 'pt_BR/pt_br_translation.dart';
  19. import 'vi_VN/vi_vn_translation.dart';
  20. import 'id_ID/id_id_translation.dart';
  21. import 'tl_PH/tl_ph_translation.dart';
  22. import 'th_TH/th_th_translation.dart';
  23. import 'hi_IN/hi_in_translation.dart';
  24. import 'tr_TR/tr_tr_translation.dart';
  25. import 'strings_enum.dart';
  26. class LocalizationService extends Translations {
  27. // prevent creating instance
  28. LocalizationService._();
  29. static LocalizationService? _instance;
  30. static LocalizationService getInstance() {
  31. _instance ??= LocalizationService._();
  32. return _instance!;
  33. }
  34. // 根据系统语言获取默认语言
  35. static Locale getDefaultLanguage() {
  36. // 获取系统语言代码
  37. final String deviceLanguage =
  38. WidgetsBinding.instance.platformDispatcher.locale.languageCode;
  39. // 检查系统语言是否在支持的语言列表中
  40. if (isLanguageSupported(deviceLanguage)) {
  41. return supportedLanguages[deviceLanguage]!;
  42. }
  43. // 如果系统语言不受支持,则返回英语作为默认语言
  44. return supportedLanguages['en']!;
  45. }
  46. // 获取系统国家
  47. static String getSystemCountry() {
  48. return WidgetsBinding.instance.platformDispatcher.locale.countryCode ?? '';
  49. }
  50. // default language
  51. // todo change the default language
  52. static Locale defaultLanguage = getDefaultLanguage();
  53. static final all = [
  54. const Locale('en'), // 英语
  55. // const Locale('es'), // 西班牙语
  56. // const Locale('ar'), // 阿拉伯语
  57. // const Locale('de'), // 德语
  58. // const Locale('ja'), // 日语
  59. // const Locale('fr'), // 法语
  60. // const Locale('ru'), // 俄语
  61. // const Locale('ko'), // 韩语
  62. // const Locale('fa'), // 波斯语
  63. // const Locale('my'), // 缅甸语
  64. // const Locale('zh', 'TW'), // 繁体中文
  65. // const Locale('zh', 'CN'), // 简体中文
  66. // const Locale('tk'), // 土库曼语
  67. // const Locale('pt', 'BR'), // 葡萄牙语-巴西
  68. // const Locale('vi'), // 越南语
  69. // const Locale('id'), // 印尼语
  70. // const Locale('tl'), // 菲律宾语
  71. // const Locale('th'), // 泰语
  72. // const Locale('hi'), // 印地语
  73. // const Locale('tr'), // 土耳其语
  74. ];
  75. // supported languages
  76. static Map<String, Locale> supportedLanguages = {
  77. 'en': const Locale('en', 'US'),
  78. // 'es': const Locale('es', 'ES'),
  79. // 'ar': const Locale('ar', 'AR'),
  80. // 'de': const Locale('de', 'DE'),
  81. // 'ja': const Locale('ja', 'JP'),
  82. // 'fr': const Locale('fr', 'FR'),
  83. // 'ru': const Locale('ru', 'RU'),
  84. // 'ko': const Locale('ko', 'KR'),
  85. // 'fa': const Locale('fa', 'IR'),
  86. // 'my': const Locale('my', 'MM'),
  87. 'zh': const Locale('zh', 'CN'), // 默认简体中文(系统语言检测用)
  88. // 'zh_TW': const Locale('zh', 'TW'), // 繁体中文
  89. 'zh_CN': const Locale('zh', 'CN'), // 简体中文(语言选择器用)
  90. // 'tk': const Locale('tk', 'TM'),
  91. // 'pt': const Locale('pt', 'BR'),
  92. // 'vi': const Locale('vi', 'VN'),
  93. // 'id': const Locale('id', 'ID'),
  94. // 'tl': const Locale('tl', 'PH'),
  95. // 'th': const Locale('th', 'TH'),
  96. // 'hi': const Locale('hi', 'IN'),
  97. // 'tr': const Locale('tr', 'TR'),
  98. };
  99. // supported languages fonts family (must be in assets & pubspec yaml) or you can use google fonts
  100. static Map<String, TextStyle> supportedLanguagesFontsFamilies = {
  101. // 'en': GoogleFonts.poppins(),
  102. // 'es': GoogleFonts.poppins(),
  103. // 'ar': GoogleFonts.cairo(),
  104. // 'fa': GoogleFonts.vazirmatn(),
  105. // 'my': GoogleFonts.notoSansMyanmar(),
  106. 'en': const TextStyle(fontFamily: 'Inter'),
  107. // 'es': const TextStyle(fontFamily: 'FiraSans'),
  108. // 'ar': const TextStyle(fontFamily: 'Vazirmatn'),
  109. // 'de': const TextStyle(fontFamily: 'FiraSans'),
  110. // 'ja': const TextStyle(fontFamily: 'FiraSans'),
  111. // 'fr': const TextStyle(fontFamily: 'FiraSans'),
  112. // 'ru': const TextStyle(fontFamily: 'FiraSans'),
  113. // 'ko': const TextStyle(fontFamily: 'FiraSans'),
  114. // 'fa': const TextStyle(fontFamily: 'Vazirmatn'),
  115. // 'my': const TextStyle(fontFamily: 'NotoSansMyanmar'),
  116. 'zh': const TextStyle(fontFamily: 'FiraSans'),
  117. // 'zh_TW': const TextStyle(fontFamily: 'FiraSans'),
  118. 'zh_CN': const TextStyle(fontFamily: 'FiraSans'),
  119. // 'tk': const TextStyle(fontFamily: 'FiraSans'),
  120. // 'pt': const TextStyle(fontFamily: 'FiraSans'),
  121. // 'vi': const TextStyle(fontFamily: 'FiraSans'),
  122. // 'id': const TextStyle(fontFamily: 'FiraSans'),
  123. // 'tl': const TextStyle(fontFamily: 'FiraSans'),
  124. // 'th': const TextStyle(fontFamily: 'FiraSans'),
  125. // 'hi': const TextStyle(fontFamily: 'FiraSans'),
  126. // 'tr': const TextStyle(fontFamily: 'FiraSans'),
  127. };
  128. @override
  129. Map<String, Map<String, String>> get keys => {
  130. 'en_US': enUs,
  131. // 'es_ES': esEs,
  132. // 'ar_AR': arAR,
  133. // 'de_DE': deDE,
  134. // 'ja_JP': jaJP,
  135. // 'fr_FR': frFR,
  136. // 'ru_RU': ruRU,
  137. // 'ko_KR': koKR,
  138. // 'fa_IR': faIR,
  139. // 'my_MM': myMM,
  140. // 'zh_TW': zhTW,
  141. 'zh_CN': zhCN,
  142. // 'tk_TM': tkTM,
  143. // 'pt_BR': ptBR,
  144. // 'vi_VN': viVN,
  145. // 'id_ID': idID,
  146. // 'tl_PH': tlPH,
  147. // 'th_TH': thTH,
  148. // 'hi_IN': hiIN,
  149. // 'tr_TR': trTR,
  150. };
  151. /// check if the language is supported
  152. static isLanguageSupported(String languageCode) =>
  153. supportedLanguages.keys.contains(languageCode);
  154. /// update app language by code language for example (en,ar..etc)
  155. static updateLanguage(String languageCode) async {
  156. // check if the language is supported
  157. if (!isLanguageSupported(languageCode)) return;
  158. // update current language in shared pref
  159. await IXSP.setCurrentLanguage(languageCode);
  160. if (!Get.testMode) {
  161. Get.updateLocale(supportedLanguages[languageCode]!);
  162. }
  163. }
  164. /// check if the language is english
  165. static bool isItEnglish() =>
  166. IXSP.getCurrentLocal().languageCode.toLowerCase().contains('en');
  167. /// get current locale
  168. static Locale getCurrentLocal() => IXSP.getCurrentLocal();
  169. /// 检测指定的[languageCode]是否从右往左(RTL)布局
  170. static bool isRTL() {
  171. switch (getCurrentLocal().languageCode) {
  172. case 'ar':
  173. case 'fa':
  174. case 'he':
  175. return true;
  176. default:
  177. return false;
  178. }
  179. }
  180. /// 获取本地化配置[locale]中的语言简称
  181. static String getGlobalLanguageTitle({Locale? locale}) {
  182. final currentLocale = locale ?? getCurrentLocal();
  183. final languageCode = currentLocale.languageCode.toLowerCase();
  184. final countryCode = currentLocale.countryCode?.toUpperCase() ?? '';
  185. // 中文需要区分简体和繁体
  186. if (languageCode == 'zh') {
  187. return countryCode == 'TW' ? Strings.zhTWLang.tr : Strings.zhCNLang.tr;
  188. }
  189. switch (languageCode) {
  190. case 'en':
  191. return Strings.enLang.tr;
  192. case 'es':
  193. return Strings.esLang.tr;
  194. case 'ar':
  195. return Strings.arLang.tr;
  196. case 'de':
  197. return Strings.deLang.tr;
  198. case 'ja':
  199. return Strings.jaLang.tr;
  200. case 'fr':
  201. return Strings.frLang.tr;
  202. case 'ru':
  203. return Strings.ruLang.tr;
  204. case 'ko':
  205. return Strings.koLang.tr;
  206. case 'fa':
  207. return Strings.faLang.tr;
  208. case 'my':
  209. return Strings.myLang.tr;
  210. case 'tk':
  211. return Strings.tkLang.tr;
  212. case 'pt':
  213. return Strings.ptBRLang.tr;
  214. case 'vi':
  215. return Strings.viLang.tr;
  216. case 'id':
  217. return Strings.idLang.tr;
  218. case 'tl':
  219. return Strings.tlLang.tr;
  220. case 'th':
  221. return Strings.thLang.tr;
  222. case 'hi':
  223. return Strings.hiLang.tr;
  224. case 'tr':
  225. return Strings.trLang.tr;
  226. default:
  227. return 'Unknown';
  228. }
  229. }
  230. /// 获取本地化配置[locale]中的语言全称
  231. static String getGlobalLanguageName({Locale? locale}) {
  232. final currentLocale = locale ?? getCurrentLocal();
  233. final languageCode = currentLocale.languageCode.toLowerCase();
  234. final countryCode = currentLocale.countryCode?.toUpperCase() ?? '';
  235. // 中文需要区分简体和繁体
  236. if (languageCode == 'zh') {
  237. return countryCode == 'TW' ? '繁體中文' : '简体中文';
  238. }
  239. switch (languageCode) {
  240. case 'en':
  241. return 'English';
  242. case 'tr':
  243. return 'Türkçe';
  244. case 'vi':
  245. return 'Tiếng Việt';
  246. case 'uk':
  247. return 'Українська';
  248. case 'es':
  249. return 'Español';
  250. case 'ru':
  251. return 'Русский';
  252. case 'pt':
  253. return 'Português (Brasil)';
  254. case 'pl':
  255. return 'Polski';
  256. case 'ko':
  257. return '한국어';
  258. case 'ja':
  259. return '日本語';
  260. case 'it':
  261. return 'Italiano';
  262. case 'id':
  263. return 'Bahasa Indonesia';
  264. case 'de':
  265. return 'Deutsch';
  266. case 'fr':
  267. return 'Français';
  268. case 'fa':
  269. return 'فارسی';
  270. case 'hi':
  271. return 'हिन्दी';
  272. case 'ar':
  273. return 'عربي';
  274. case 'my':
  275. return 'မြန်မာဘာသာ';
  276. case 'tk':
  277. return 'Türkmençe';
  278. case 'tl':
  279. return 'Filipino';
  280. case 'th':
  281. return 'ไทย';
  282. default:
  283. return 'Unknown';
  284. }
  285. }
  286. }