I know the question is pretty old, but I found it as I had the same problem and was searching for a solution. I was not able to find one on the Internet so I was trying to solve it by myself and as I made it, I want to present here my solution. This solution might not be the most nice one as I am pretty new to Dart/Flutter but at least it works.
As the Owner of the question did not provide his setup I will take the state of this Video as given.
[...]
Map<String, String> _localizeStrings;
[...]
_localizeStrings = jsonMap.map((key, value) {
return MapEntry(key, value.toString());
});
[...]
String translate(String key) {
return _localizeStrings[key];
}
[...]
That is the given state, which is totally setup for a flat json structure. To be able to work with a nested structure our Map _localizeStrings
should be of type Map<String, dynamic>
as the key will always be a String but the value could either be a String or another map. As a next step we need to remove the .toString()
from value
. As a last step we will implement a function which is splitting the given key by '.' and will climb down the map key by key. The last value it gets we will return with .toString()
as this should be the string we want to have.
So here is my solution:
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;
}