Android 在headless模式下获取本地化字符串
我目前正在尝试以无头模式运行应用程序,我所做的是定义了后台回调:Android 在headless模式下获取本地化字符串,android,flutter,headless,Android,Flutter,Headless,我目前正在尝试以无头模式运行应用程序,我所做的是定义了后台回调: void callbackInBackground() { // Invoked from the service } 我正试图从回调中获取具有当前区域设置的本地化字符串 因为我需要BuildContext来实现这一点,所以我不知道如何检索它们 有什么提示和窍门吗?您可以使用该插件来实现这一点。此外,您还可以使用插件进行无头执行 易于实现本地化的示例: import 'dart:developer'; import 'dart
void callbackInBackground() {
// Invoked from the service
}
我正试图从回调中获取具有当前区域设置的本地化字符串
因为我需要BuildContext
来实现这一点,所以我不知道如何检索它们
有什么提示和窍门吗?您可以使用该插件来实现这一点。此外,您还可以使用插件进行无头执行
易于实现本地化的示例:
import 'dart:developer';
import 'dart:ui';
import 'lang_view.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:easy_localization_loader/easy_localization_loader.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'generated/locale_keys.g.dart';
void main() {
runApp(EasyLocalization(
child: MyApp(),
supportedLocales: [
Locale('en', 'US'),
Locale('ar', 'DZ'),
Locale('de', 'DE'),
Locale('ru', 'RU')
],
path: 'resources/langs/langs.csv', //'resources/langs',
// fallbackLocale: Locale('en', 'US'),
// startLocale: Locale('de', 'DE'),
// saveLocale: false,
// useOnlyLangCode: true,
// preloaderColor: Colors.black,
// preloaderWidget: CustomPreloaderWidget(),
// optional assetLoader default used is RootBundleAssetLoader which uses flutter's assetloader
// install easy_localization_loader for enable custom loaders
// assetLoader: RootBundleAssetLoader()
// assetLoader: HttpAssetLoader()
// assetLoader: FileAssetLoader()
assetLoader: CsvAssetLoader()
// assetLoader: YamlAssetLoader() //multiple files
// assetLoader: YamlSingleAssetLoader() //single file
// assetLoader: XmlAssetLoader() //multiple files
// assetLoader: XmlSingleAssetLoader() //single file
// assetLoader: CodegenLoader()
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
log(context.locale.toString(),
name: '${this} # locale Context');
log('title'.tr().toString(), name: '${this} # locale');
return MaterialApp(
title: 'title'.tr(),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Easy localization'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int counter = 0;
bool _gender = true;
void incrementCounter() {
setState(() {
counter++;
});
}
void switchGender(bool val) {
setState(() {
_gender = val;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(LocaleKeys.title).tr(context: context),
//Text(AppLocalizations.of(context).tr('title')),
actions: <Widget>[
FlatButton(
child: Icon(Icons.language),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => LanguageView(), fullscreenDialog: true),
);
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(
flex: 1,
),
Text(
LocaleKeys.gender_with_arg,
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 19,
fontWeight: FontWeight.bold),
).tr(args: ['aissat'], gender: _gender ? 'female' : 'male'),
Text(
tr(LocaleKeys.gender, gender: _gender ? 'female' : 'male'),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 15,
fontWeight: FontWeight.bold),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(FontAwesome.male),
Switch(value: _gender, onChanged: switchGender),
Icon(FontAwesome.female),
],
),
Spacer(
flex: 1,
),
Text(LocaleKeys.msg).tr(args: ['aissat', 'Flutter']),
Text(LocaleKeys.msg_named).tr(namedArgs: {'lang': 'Dart'}, args: ['Easy localization']),
Text(LocaleKeys.clicked).plural(counter),
FlatButton(
onPressed: () {
incrementCounter();
},
child: Text(LocaleKeys.clickMe).tr(),
),
SizedBox(
height: 15,
),
Text(
plural(LocaleKeys.amount, counter,
format: NumberFormat.currency(
locale: Intl.defaultLocale, symbol: '€')),
style: TextStyle(
color: Colors.grey.shade900,
fontSize: 18,
fontWeight: FontWeight.bold)),
SizedBox(
height: 20,
),
RaisedButton(
onPressed: () {
context.deleteSaveLocale();
},
child: Text(LocaleKeys.reset_locale).tr(),
),
Spacer(
flex: 1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: incrementCounter,
child: Text('+1'),
),
);
}
}
class CustomPreloaderWidget extends StatelessWidget {
const CustomPreloaderWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
log('Loading custom preloder widget');
return Container(
child: Center(
child: CircularProgressIndicator()
),
);
}
}
导入“dart:developer”;
导入“dart:ui”;
导入“lang_view.dart”;
进口“包装:颤振/材料.省道”;
导入“package:easy_localization/easy_localization.dart”;
导入“包:easy_localization_loader/easy_localization_loader.dart”;
导入“包:颤振图标/颤振图标.dart”;
导入“生成的/locale_keys.g.dart”;
void main(){
runApp(易本地化)(
子项:MyApp(),
支持的区域设置:[
地区('en','US'),
语言环境('ar','DZ'),
语言环境('de','de'),
区域设置('ru','ru')
],
路径:'resources/langs/langs.csv',//'resources/langs',
//后备语言环境:语言环境('en','US'),
//startLocale:Locale('de','de'),
//saveLocale:false,
//useOnlyLangCode:true,
//颜色:颜色。黑色,
//PreforeWidget:CustomPreforeWidget(),
//默认使用的可选assetLoader是RootBundleAssetLoader,它使用Flatter的assetLoader
//安装easy_localization_loader以启用自定义加载程序
//assetLoader:RootBundleAsetLoader()
//assetLoader:HttpAssetLoader()
//assetLoader:FileAssetLoader()
assetLoader:CsvAssetLoader()
//assetLoader:YamlAssetLoader()//多个文件
//assetLoader:YamlSingleAssetLoader()//单个文件
//assetLoader:XmlAssetLoader()//多个文件
//assetLoader:XmlSingleAssetLoader()//单个文件
//assetLoader:CodegenLoader()
));
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
日志(context.locale.toString(),
名称:“${this}#locale Context”);
日志('title'.tr().toString(),名称:'${this}#locale');
返回材料PP(
标题:'title'.tr(),
localizationsDelegates:context.localizationDelegates,
supportedLocales:context.supportedLocales,
locale:context.locale,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“轻松本地化”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
int计数器=0;
bool_性别=真;
void incrementCounter(){
设置状态(){
计数器++;
});
}
无效切换性别(布尔值){
设置状态(){
_性别=val;
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:Text(LocaleKeys.title).tr(context:context),
//Text(AppLocalizations.of(context.tr('title')),
行动:[
扁平按钮(
子:图标(Icons.language),
已按下:(){
导航器。推(
上下文
材料路线(
生成器:()=>LanguageView(),fullscreenDialog:true),
);
},
),
],
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
间隔棒(
弹性:1,
),
正文(
LocaleKeys.gender_和_arg,
样式:TextStyle(
颜色:Colors.grey.shade600,
尺码:19,
fontWeight:fontWeight.bold),
).tr(args:['aissat',性别:_性别?'femal':'male'),
正文(
tr(LocaleKeys.gender,gender:_gender?'femal':'male'),
样式:TextStyle(
颜色:Colors.grey.shade600,
尺寸:15,
fontWeight:fontWeight.bold),
),
划船(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
图标(真棒,男性),
开关(值:\性别,一旦更改:开关性别),
图标(真棒,女性),
],
),
间隔棒(
弹性:1,
),
Text(LocaleKeys.msg).tr(args:['aissat','flatter']),
Text(LocaleKeys.msg_named).tr(namedArgs:{'lang':'Dart'},args:['Easy localization']),
文本(LocaleKeys.clicked)。复数(计数器),
扁平按钮(
已按下:(){
递增计数器();
},
child:Text(LocaleKeys.clickMe).tr(),
),
大小盒子(
身高:15,
),
正文(
复数(LocaleKeys.amount、counter、,
格式:NumberFormat.currency(
语言环境:Intl.defaultLocale,符号:“€”),
样式:TextStyle(
颜色:Colors.grey.shade900,
尺码:18,
fontWeight:fontWeight.bold),
大小盒子(
身高:20,
),
升起的按钮(
已按下:(){
deleteSaveLocale();
},
child:Text(LocaleKeys.reset_locale.tr(),
),
间隔棒(
弹性:1,
),
],
),
),
浮动操作按钮:浮动操作按钮(
按下:递增计数器,
子项:文本(“+1”),
),
);
}
}
类CustomPrewareWidget扩展了无状态小部件{
const custompreforderwidget({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
日志(
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'app_localizations.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// List all of the app's supported locales here
supportedLocales: [
Locale('en', 'US'),
Locale('sk', 'SK'),
],
// These delegates make sure that the localization data for the proper language is loaded
localizationsDelegates: [
// A class which loads the translations from JSON files
AppLocalizations.delegate,
// Built-in localization of basic text for Material widgets
GlobalMaterialLocalizations.delegate,
// Built-in localization for text direction LTR/RTL
GlobalWidgetsLocalizations.delegate,
],
// Returns a locale which will be used by the app
localeResolutionCallback: (locale, supportedLocales) {
// Check if the current device locale is supported
for (var supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale.languageCode &&
supportedLocale.countryCode == locale.countryCode) {
return supportedLocale;
}
}
// If the locale of the device is not supported, use the first one
// from the list (English, in this case).
return supportedLocales.first;
},
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
AppLocalizations.of(context).translate('first_string'),
style: TextStyle(fontSize: 25),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
Text(
AppLocalizations.of(context).translate('second_string'),
style: TextStyle(fontSize: 25),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
Text(
'This will not be translated.',
style: TextStyle(fontSize: 25),
textAlign: TextAlign.center,
),
],
),
),
),
);
}
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class AppLocalizations {
final Locale locale;
AppLocalizations(this.locale);
// 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);
}
// Static member to have a simple access to the delegate from the MaterialApp
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
Map<String, String> _localizedStrings;
Future<bool> load() async {
// Load the language JSON file from the "lang" folder
String jsonString =
await rootBundle.loadString('lang/${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
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', 'sk'].contains(locale.languageCode);
}
@override
Future<AppLocalizations> load(Locale locale) async {
// AppLocalizations class is where the JSON loading actually runs
AppLocalizations localizations = new AppLocalizations(locale);
await localizations.load();
return localizations;
}
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}