首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在json文件中使用动态字符串实现颤振国际化

在json文件中使用动态字符串实现颤振国际化
EN

Stack Overflow用户
提问于 2020-05-25 14:59:50
回答 4查看 4.9K关注 0票数 6

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

下面是一个例子:

代码语言:javascript
复制
AppLocalizations.of(context).userAge(18)

在AppLocalizations.dart上:

代码语言:javascript
复制
userAge(age) => Intl.message(
  "My age is $age",
  name: "userAge",
  args: [age]);
// Return "My age is 18"

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

有什么解决方案吗?

EN

回答 4

Stack Overflow用户

发布于 2020-06-19 18:06:24

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

代码语言:javascript
复制
final age = 18 //user input.
final ageString = 'user_age'
                   .localisedString()
                   .replaceAll(new RegExp(r'\${age}'), age)

en.json

代码语言:javascript
复制
{
  "user_age": "My age is ${age}",
  "user_name_age": "My name is ${name} and age is ${age}"
}

string_extension.dart

代码语言:javascript
复制
extension Localisation on String {
  String localisedString() {
    return stringBy(this) ?? '';
  }
}

另外,你也可以这样做,

代码语言:javascript
复制
  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})

app_localisation.dart

代码语言:javascript
复制
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;
}
票数 9
EN

Stack Overflow用户

发布于 2020-06-14 00:04:06

  1. 在您的assets目录中创建一个文件夹,名为json。把你的语言文件放进去。

assets json - en.json //对于英语- ru.json //对于现在在en.json中的俄语

  • ,例如,写下你的字符串。

{ "myAge":“我的年龄是”}

类似地,在ru.json中,

{ "myAge":“Мойвозраст”}

  • 将此代码添加到pubspec.yaml文件(注意空格)

flutter: uses-material-design:真实资产:- assets/json/

运行flutter pub get

初步工作已完成。让我们转到代码端。

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

代码语言:javascript
复制
Map<String, dynamic> language;

class AppLocalizations {
  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

  String getText(String key) => language[key];

  String userAge(int age) => '${getText('myAge')} $age';
}

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'ru'].contains(locale.languageCode);

  @override
  Future<AppLocalizations> load(Locale locale) async {
    final string = await rootBundle.loadString('assets/json/${locale.languageCode}.json');
    language = json.decode(string);
    return SynchronousFuture<AppLocalizations>(AppLocalizations());
  }

  @override
  bool shouldReload(AppLocalizationsDelegate old) => false;
}

MaterialApp小部件中设置以下内容:

代码语言:javascript
复制
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(),
    ),
  );
}

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

代码语言:javascript
复制
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();
  }
}
票数 7
EN

Stack Overflow用户

发布于 2020-06-19 16:47:24

我尝试过各种实现本地化的解决方案,我遇到的最好的是Localizely.com (非附属公司)为VS CodeAndroid Studio/IntelliJ开发的Flutter Intl插件。

使用它,基本上是使用marketplace/plugin库安装插件,然后使用菜单选项为您的项目进行初始化。这将在lib/l10n/intlen.arb中创建一个默认的英语语言环境(听起来很可怕,但实际上只是JSON),并为lib/generated中的国际化搭建了所有的脚手架。

您还必须将以下内容添加到依赖项中。

代码语言:javascript
复制
flutter_localizations:
    sdk: flutter

然后,您可以将密钥添加到此文件中,通过导入包含名为S的类的generated/l10n.dart,这些密钥将自动在您的应用程序中可用。

要让flutter使用它,无论您在何处初始化MaterialApp,请确保将S.delegate传递到MaterialApp的localizationsDelegates参数(很可能是包含GlobalMaterialLocalizations.delegateGlobalWidgetsLocalizations.delegateGlobalCupertinoLocalizations.delegate的数组的一部分)。您还必须将S.delegate.supportedLocales添加到MaterialApp的supportedLocales中。

要添加更多语言环境,请使用菜单中的选项(至少在intellij中)或简单地创建更多intl_.arb文件,插件将自动识别并设置相关代码。

假设您有一个包含以下内容的intl_en文件:

代码语言:javascript
复制
{ "name": "Name" }

然后使用S.of(context).name在代码中使用该字符串。

所有这些在localizely的网站上都有更有说服力的解释。

现在,要在这些.arb文件中使用密钥,只需将其包装在{...}中。举个例子:

代码语言:javascript
复制
{ "choose1OfNumOptions": "Choose 1 of {numoptions} options" }

将导致S.of(context).choose1OfNumOptions(numOptions);的使用。我不知道这个插件是否支持完整的ARB specification,但它至少支持基本的功能。

此外,我没有使用Localizely,但它似乎是一种非常有用的方式来管理翻译和插件的自动集成,尽管我认为它的价格也太高了-至少对我的应用程序来说,它恰好有大量的文本。实际上,我只有一个谷歌工作表,我在其中存储了我所有的翻译,当需要更新它时,我将其作为.tsv下载,并编写了一个简单的小解析器来写入.arb文件。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61997301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档