使用json文件中的动态字符串进行颤振国际化

Sim*_*pps 5 json flutter flutter-intl

到目前为止,我使用的是动态字符串,如本文的解决方案所示: Flutter 国际化 - 动态字符串

下面是一个例子:

AppLocalizations.of(context).userAge(18)
Run Code Online (Sandbox Code Playgroud)

在 AppLocalizations.dart 上:

userAge(age) => Intl.message(
  "My age is $age",
  name: "userAge",
  args: [age]);
// Return "My age is 18"
Run Code Online (Sandbox Code Playgroud)

但后来我读了这篇关于颤振国际化的文章:https : //medium.com/flutter-community/flutter-internationalization-the-easy-way-using-provider-and-json-c47caa4212b2 其中展示了如何使用 json 文件进行本地化字符串的资源文件。它看起来更方便,所以我更喜欢使用这种方法,但不知道如何从具有动态值的 json 文件中获取字符串。

有什么解决办法吗?

Tap*_*Pal 8

要从 JSON 文件中获取具有动态值的字符串,您可以使用

final age = 18 //user input.
final ageString = 'user_age'
                   .localisedString()
                   .replaceAll(new RegExp(r'\${age}'), age)
Run Code Online (Sandbox Code Playgroud)

en.json

{
  "user_age": "My age is ${age}",
  "user_name_age": "My name is ${name} and age is ${age}"
}
Run Code Online (Sandbox Code Playgroud)

string_extension.dart

extension Localisation on String {
  String localisedString() {
    return stringBy(this) ?? '';
  }
}
Run Code Online (Sandbox Code Playgroud)

另外,你可以做类似的事情,

  String localisedString(Map<String, String> args) {
      String str = localisedString();
      args.forEach((key, value) { 
        str = str.replaceAll(new RegExp(r'\${'+key+'}'), value);
      });
      return str;
  }
  
  //usecase
  final userName = 'Spider Man'
  final age = '18'
  final nameAgeString = 'user_name_age'.localisedString({'name': userName, 'age': age})
Run Code Online (Sandbox Code Playgroud)

app_localisation.dart

Map<String, dynamic> _language;

String stringBy(String key) => _language[key] as String ?? 'null';

class AppLocalisationDelegate extends LocalizationsDelegate {
  const AppLocalisationDelegate();

  // override the following method if you want to specify the locale you are supporting.
  final _supportedLocale = ['en'];
  @override
  bool isSupported(Locale locale) => _supportedLocale.contains(locale.languageCode);

  @override
  Future load(Locale locale) async {
    String jsonString = await rootBundle
        .loadString("assets/strings/${locale.languageCode}.json");

    _language = jsonDecode(jsonString) as Map<String, dynamic>;
    print(_language.toString());
    return SynchronousFuture<AppLocalisationDelegate>(
        AppLocalisationDelegate());
  }

  @override
  bool shouldReload(AppLocalisationDelegate old) => false;
}
Run Code Online (Sandbox Code Playgroud)


Cop*_*oad 6

  1. json在您的assets目录中创建一个文件夹。将您的语言文件放入其中。

    assets
      json
       - en.json // for English 
       - ru.json  // for Russian
    
    Run Code Online (Sandbox Code Playgroud)
  2. en.json例如,现在在中写入您的字符串。

    {
      "myAge": "My age is"
    }
    
    Run Code Online (Sandbox Code Playgroud)

    类似地,在ru.json

    {
      "myAge": "??? ???????"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将此添加到pubspec.yaml文件中(注意空格)

    flutter:
    
      uses-material-design: true
    
      assets:
        - assets/json/
    
    Run Code Online (Sandbox Code Playgroud)

    flutter pub get


初步工作完成。让我们转到代码方面。

将此样板代码复制到您的文件中:

assets
  json
   - en.json // for English 
   - ru.json  // for Russian
Run Code Online (Sandbox Code Playgroud)

MaterialApp小部件中设置一些东西:

void main() {
  runApp(
    MaterialApp(
      locale: Locale('ru'), // switch between "en" and "ru" to see effect
      localizationsDelegates: [const AppLocalizationsDelegate()],
      supportedLocales: [const Locale('en'), const Locale('ru')],
      home: HomePage(),
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以简单地使用上面的委托:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var age = AppLocalizations.of(context).userAge(18);
    // prints "My age is 18" for 'en' and "??? ??????? 18" for 'ru' locale. 
    print(age); 

    return Scaffold();
  }
}
Run Code Online (Sandbox Code Playgroud)