cra*_*ear 6 json localization flutter
我是扑的新手。
我在我的 flutter 项目中应用了本地化,一切正常,直到我编辑我的 json 语言文件以具有嵌套对象。
如何正确调用嵌套的json对象?
我尝试使用点来调用它,但它抛出错误“必须提供非空字符串...”
AppLocalizations.of(context).translate('Intro.Header')
Run Code Online (Sandbox Code Playgroud)
这是我的 json
{
"Intro": {
"Header": "Introduction",
"Content": "This is...."
},
"Test": "This is test",
}
Run Code Online (Sandbox Code Playgroud)
如果我直接调用“测试”,我没有问题。
AppLocalizations.of(context).translate('Test')
Run Code Online (Sandbox Code Playgroud)
如何阅读标题和内容?
小智 2
我知道这个问题很老了,但我发现它是因为我遇到了同样的问题并正在寻找解决方案。我无法在互联网上找到一个解决方案,所以我试图自己解决它,当我做到这一点时,我想在这里展示我的解决方案。这个解决方案可能不是最好的,因为我对 Dart/Flutter 还很陌生,但至少它有效。
由于问题的所有者没有提供他的设置,我将采用给定的该视频的状态。
[...]
Map<String, String> _localizeStrings;
[...]
_localizeStrings = jsonMap.map((key, value) {
return MapEntry(key, value.toString());
});
[...]
String translate(String key) {
return _localizeStrings[key];
}
[...]
Run Code Online (Sandbox Code Playgroud)
这就是给定的状态,它完全是为平面 json 结构设置的。为了能够使用嵌套结构,我们的映射_localizeStrings应该是类型Map<String, dynamic>,因为键始终是字符串,但值可以是字符串或另一个映射。下一步我们需要.toString()从 中删除value. 作为最后一步,我们将实现一个用“.”分割给定键的函数。并会一键一键地沿着地图向下爬。我们将返回它获得的最后一个值,.toString()因为这应该是我们想要的字符串。
所以这是我的解决方案:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class AppLocalizations {
final Locale locale;
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
AppLocalizations(this.locale);
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
Map<String, dynamic> _localizeStrings;
Future<bool> load() async {
String jsonString =
await rootBundle.loadString('lang/${locale.languageCode}.json');
Map<String, dynamic> jsonMap = json.decode(jsonString);
_localizeStrings = jsonMap.map((key, value) {
return MapEntry(key, value);
});
return true;
}
String translate(String key) {
var nestedMap = _getNestedValue(key);
return nestedMap.toString();
}
dynamic _getNestedValue(String keyPath) {
Map keyMap = keyPath.split('.').asMap();
var nestedMap;
keyMap.forEach((index, key) {
if (index == 0) {
nestedMap = _localizeStrings[key];
} else
nestedMap = nestedMap[key];
});
return nestedMap;
}
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['en', 'de'].contains(locale.languageCode);
}
@override
Future<AppLocalizations> load(Locale locale) async {
AppLocalizations localizations = new AppLocalizations(locale);
await localizations.load();
return localizations;
}
@override
bool shouldReload(LocalizationsDelegate<AppLocalizations> old) => false;
}
Run Code Online (Sandbox Code Playgroud)