今日的程序码 => GITHUB
这边我想要介绍如何切换语言、设定 App 初始的语言,且下此开启 App 时也会记住已经被切换过的语言。
这边的教学,功能正常,但写法不一定是最好的。这边推荐另外的套件
flutter_localizations:
sdk: flutter
shared_preferences: ^2.0.7
- - - - - - - - - - - - - - - - - - - - -
assets:
- language/
建立一个 language 在专案目录底下建立两个 Json
{
"name": "flutter_localizations example",
"introduce": "Hello"
}
{
"name": "语言切换范例",
"introduce" : "你好呀"
}
会给予 sharedpreferences
一个预设的语言 data(zh)
,手机一打开时,会在 didChangeDependencies
里面去读取 sharedpreferences
,进而去设定 local
的地区是属於什麽。
supportedLocales
= App 要支援的语言localizationsDelegates
= 委托确保加载正确语言的本地化数据localeResolutionCallback
= 检查手机是否支援这个语言locale
= 现在手机的语言是什麽AppLocalizations
= 是我们自己建立管理语言的一个 class
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
/// 当地区更改时,重新设定地区,当使用者按下变换语言时,会触发。
static void setLocale(BuildContext context, Locale newLocale) {
_MyAppState? state = context.findAncestorStateOfType<_MyAppState>();
state!.changeLocale(newLocale);
}
}
class _MyAppState extends State<MyApp> {
Locale _locale = new Locale.fromSubtags(languageCode: 'zh');
/// 更改地区
void changeLocale(Locale locale) {
setState(() {
this._locale = locale;
});
}
@override
void didChangeDependencies() async {
super.didChangeDependencies();
final languageApp = AppLocalizations();
final localeKey = await languageApp.readLocaleKey();
if (localeKey == "en") {
this._locale = new Locale("en", "EN");
} else {
this._locale = new Locale.fromSubtags(languageCode: 'zh');
}
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
supportedLocales: [
Locale('en', 'US'),
const Locale.fromSubtags(languageCode: 'zh'),
],
// These delegates make sure that the localization data for the proper language is loaded
// 委托确保加载正确语言的本地化数据
localizationsDelegates: [
// This class will be added later
// A class which loads the translations from JSON files
AppLocalizations.delegate,
// A class which loads the translations from JSON files
GlobalMaterialLocalizations.delegate,
// Built-in localization of basic text for Material widgets
GlobalWidgetsLocalizations.delegate,
],
locale: _locale,
// Returns a locale which will be used by the app
localeResolutionCallback: (locale, supportedLocales) {
// Check if the current device locale is supported
// 检查手机是否支援这个语言
for (var supportedLocaleLanguage in supportedLocales) {
if (supportedLocaleLanguage.languageCode == locale?.languageCode &&
supportedLocaleLanguage.countryCode == locale?.countryCode) {
return supportedLocaleLanguage;
}
}
// If device not support with locale to get language code then default get first on from the list
return supportedLocales.first;
},
home: HomePage());
}
}
class AppLocalizations {
final Locale locale;
AppLocalizations({this.locale = const Locale.fromSubtags(languageCode: 'zh')});
/// Helper method to keep the code in the widgets concise
/// Localizations are accessed using an InheritedWidget "of" syntax
/// 访问本地化
static AppLocalizations? of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
/// 储存 SharedPreferences
void keepLocaleKey(String localeKey) async {
final _prefs = await SharedPreferences.getInstance();
await _prefs.remove("localeKey");
await _prefs.setString("localeKey", localeKey);
}
/// 读取 SharedPreferences
Future<String> readLocaleKey() async {
final _prefs = await SharedPreferences.getInstance();
// 初始化最一刚开始的语言
return _prefs.getString("localeKey")??'zh';
}
/// 更改语言,重新设定语言
void setLocale(BuildContext context, Locale locale) async {
// keep value in shared pref
keepLocaleKey(locale.languageCode);
print("key language :${locale.languageCode}");
MyApp.setLocale(context, locale);
}
/// Static member to have a simple access to the delegate from the MaterialApp
/// 提供 Main Page 可以直接访问。
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
late Map<String, String> _localizedStrings;
/// Load the language JSON file from the "lang" folder
/// 读取 Json 格式
Future<bool> load() async {
String jsonString =
await rootBundle.loadString('language/${locale.languageCode}.json');
Map<String, dynamic> jsonMap = json.decode(jsonString);
_localizedStrings = jsonMap.map((key, value) {
return MapEntry(key, value.toString());
});
return true;
}
/// This method will be called from every widget which needs a localized text
/// 提供每一个需要转换语言的文字
String translate(String key) {
return _localizedStrings[key]!;
}
}
/// LocalizationsDelegate is a factory for a set of localized resources
/// In this case, the localized strings will be gotten in an AppLocalizations object
/// 本地化的字符串将在 AppLocalizations 对像中获取
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
// This delegate instance will never change (it doesn't even have fields!)
// It can provide a constant constructor.
const _AppLocalizationsDelegate();
/// 之泉的语言代码
@override
bool isSupported(Locale locale) {
// Include all of your supported language codes here
return ['en', 'zh'].contains(locale.languageCode);
}
/// 读取 Json
@override
Future<AppLocalizations> load(Locale locale) async {
// AppLocalizations class is where the JSON loading actually runs
AppLocalizations localizations = new AppLocalizations(locale: locale);
await localizations.load();
return localizations;
}
/// 使否重新 reload
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
Text(AppLocalizations.of(context)!.translate('introduce')),
AppLocalizations localeApp = AppLocalizations();
// 之後再按钮的 onPressed 里面
onPressed: () async {
if (await localeApp.readLocaleKey() == "zh") {
localeApp.setLocale(context, Locale("en", "EN"));
} else {
localeApp.setLocale(
context, Locale.fromSubtags(languageCode: 'zh'));
}
}
<<: Day12 数据图表化 - 如何建立 Visualize
用新版Visual studio 2019开启旧版SQL Server 2012的mdf档时,却出现...
前言 Vue Router 提供 Navigation Guards,可以在路由变更前後去呼叫相关的...
今天我们要介绍的是python当中的FOR回圈,所谓的回圈就是只我们如果要在某个条件下要重复做某些事...
前言 本文说明查询证券扣款帐户银行余额资讯。 程序实作 程序 # 扣款帐户余额资讯 balance ...
嗨嗨嗨!昨天使用 Notion SDK 显示我的 Notion page 里面的内容,可以在这里看看...