aissat / easy_localization

Easy and Fast internationalizing your Flutter Apps
https://pub.dev/packages/easy_localization
MIT License
886 stars 314 forks source link

Does not recognize Simplified Chinese and Traditional Chinese. #372

Open electriko3 opened 3 years ago

electriko3 commented 3 years ago

There is an option for the zh locale to use scriptCode - Hans and Hant. In order to more accurately determine which language a user is using from China.

hyouuu commented 3 years ago

Second this - very important feature for localization. Also is there a way to override locale when using .tr()? e.g. some user would set phone locale to en but prefer to use zh for a specific app

darylsze commented 3 years ago

i am looking for solution too. zh-Hant, zh-Hans are in different script code which cannot be identified by this library

FisherWL commented 2 years ago

突发奇想用一招狸猫换太子work around了一下,虽不完美但能用。 思路是牺牲一个 Locale(小语种, 偏远小国),强制替换zh_hant. 拿芬兰语(500万使用人数)+ 库克群岛(一万多人口)为例:

      ...
      useOnlyLangCode: false,
      supportedLocales: const [
        ...
        Locale('fi', 'COK'),
        ...
        ]

      // in child widget build method:
      ...
      ...
      @override
      Widget build(BuildContext context) {
         if (context.deviceLocale.scriptCode == 'Hant') {
           context.setLocale(Locale('fi', 'COK'));
       }
       return ...

and in the translation .json or .csv you prepare something like:

... fi_COK ...
... 優勝者 ...
... 熱門 ...
dkbast commented 2 years ago

I think it would be great if the asset loader could read files with language, country and script code - just wondering about the representation for this in the delegate since this would then have to be included "all the way up" if I'm not mistaken?

dennisxiaoding commented 2 years ago

zh-Hans-CN zh-Hans-TW zh-Hans-CN

in ios it should use zh-Hans. when add in to my app, it will make difference from native.

dennisxiaoding commented 2 years ago

突发奇想用一招狸猫换太子work around了一下,虽不完美但能用。 思路是牺牲一个 Locale(小语种, 偏远小国),强制替换zh_hant. 拿芬兰语(500万使用人数)+ 库克群岛(一万多人口)为例:

      ...
      useOnlyLangCode: false,
      supportedLocales: const [
        ...
        Locale('fi', 'COK'),
        ...
        ]

      // in child widget build method:
      ...
      ...
      @override
      Widget build(BuildContext context) {
         if (context.deviceLocale.scriptCode == 'Hant') {
           context.setLocale(Locale('fi', 'COK'));
       }
       return ...

and in the translation .json or .csv you prepare something like:

... fi_COK ...
... 優勝者 ...
... 熱門 ...

Country codes can be combined randomly. You can't write so many files at this time. More like zh-hant, Zh-hans points to a default file

womandroid commented 2 years ago

Here is my solution:

My supportedLocales:

supportedLocales: const [
        Locale.fromSubtags(languageCode: "en"),
        Locale.fromSubtags(languageCode: 'zh', scriptCode: "Hans"),
        Locale.fromSubtags(languageCode: 'zh', scriptCode: "Hant"),
      ]

The key is use localeListResolutionCallback:

return MaterialApp(
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      //locale: context.locale, //<---- REMOVE THIS FIRST -----
      debugShowCheckedModeBanner: false,
      localeListResolutionCallback: (systemLocales, supportedLocales) { //<---- ADD THIS -----
        var loc = systemLocales?.first;
        var def = const Locale("en");
        if (loc == null) {
          context.setLocale(def);
          return def;
        }
        if (loc.languageCode == "zh") {
          if (loc.scriptCode == "Hant") {
            var loc = const Locale.fromSubtags(languageCode: "zh", scriptCode: "Hant");
            context.setLocale(loc);
            return loc;
          } else {
            var loc = const Locale.fromSubtags(languageCode: "zh", scriptCode: "Hans");
            context.setLocale(loc);
            return loc;
          }
        } else {
          context.setLocale(def);
          return def;
        }
      },
      title: "APP TITLE",
      home: const MyHomePage(), 
    );
Kamihimmel commented 2 years ago

is this problem resolved yet?

derjohng commented 2 months ago

This locales list have no issue on Android. supportedLocales: const [Locale('en'), Locale('zh', 'TW'), Locale('zh', 'HK'), Locale('zh', 'CN')]

However, in iOS. When we choose zh-CN, we will got deviceLocale called 'zh-Hans-TW' in my Taiwan iOS. When we choose ja, we got deviceLocale with 'ja-TW'. In original selectLocaleFrom(...) method in easy_localization_controller.dart , deviceLocale 'zh-Hans-TW' will always match the Locale('zh', 'TW'), never match Locale('zh', 'CN'). So, it's not right.

I modify the selectLocaleFrom method as below. Should be fix this issue.

 static Locale selectLocaleFrom(
    List<Locale> supportedLocales,
    Locale deviceLocale, {
    Locale? fallbackLocale,
  }) {
    Locale qDeviceLocale = deviceLocale;
    String qTest = deviceLocale.toString();
     if (qTest.startsWith("zh_Hans")) qDeviceLocale = Locale("zh","CN");
    else if (qTest.startsWith("zh_Hant_HK")) qDeviceLocale = Locale("zh","HK");
    else if (qTest.startsWith("zh_Hant_TW")) qDeviceLocale = Locale("zh","TW");
    final selectedLocale = supportedLocales.firstWhere(
      (locale) => locale.supports(qDeviceLocale),
      orElse: () => _getFallbackLocale(supportedLocales, fallbackLocale),
    );

    return selectedLocale;
  }