当我在我的 Android 或 iOS 设备上运行项目时,我希望能够获取时区、语言和国家 ID。它应该从设备的位置中检测到时区、语言和国家 ID。
我可以通过内部库获得这些吗?
首先,您应该了解系统设置和应用程序设置之间的区别:
import 'dart:io';
final String defaultLocale = Platform.localeName; // Returns locale string in the form 'en_US'
import 'package:flutter/material.dart';
final List<Locale> systemLocales = WidgetsBinding.instance.window.locales; // Returns the list of locales that user defined in the system settings.
或者
import 'dart:ui';
final List<Locale> systemLocales = window.locales;
MaterialApp小部件支持本地化。它接受您决定支持的应用程序语言环境列表。这意味着您应该在小部件初始化中明确定义它们,并提供所谓的“本地化代理”,以将实际翻译为所选语言环境(localizationsDelegates
属性)。如果您的应用程序除了en_US
之外还支持其他任何语言环境,则必须提供代理。 当您请求应用程序语言环境时,您将从supportedLocales
列表中获得一个确切的值。
final Locale appLocale = Localizations.localeOf(context);
只有在MaterialApp
小部件已经初始化时才有效。您不能在MaterialApp
初始化之前使用它。显然,如果您的应用程序小部件未初始化,则无法获取其语言环境。要使用它,您必须在子组件的build
方法中调用此表达式。例如:
void main() async {
runApp(
MaterialApp(
title: 'MyApp',
home: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Show the name of the current application locale
return Text(Localizations.localeOf(context).toString());
}
}
en_US
文本(因为这是默认语言环境,我们没有提供其他内容)。由于在此示例中我们没有明确定义应用程序的任何语言环境,因此系统语言环境设置无关紧要,并且返回默认语言环境。
捕捉系统语言环境更改
要能够对系统语言环境更改做出反应,您应该使用实现了WidgetsBindingObserver
mixin的有状态小部件,并定义didChangeLocales
方法,该方法将在系统语言环境更改时被调用: @override
void didChangeLocales(List<Locale> locale) {
// This is run when system locales are changed
super.didChangeLocales(locale);
setState(() {
// Do actual stuff on the changes
});
}
总结以上内容,以下是获取启动时区域设置并在系统设置更改时做出反应的可视化示例:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Get the initial locale values
final String defaultSystemLocale = Platform.localeName;
final List<Locale> systemLocales = WidgetsBinding.instance.window.locales;
// Define locales that our app supports (no country codes, see comments below)
final appSupportedLocales = <Locale>[
Locale('ru'),
Locale('en'),
];
final MyApp myApp = MyApp(defaultSystemLocale, systemLocales);
runApp(
MaterialApp(
title: 'MyApp',
home: myApp,
supportedLocales: appSupportedLocales,
localizationsDelegates: [
// These are default localization delegates that implement the very basic translations for standard controls and date/time formats.
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
)
);
}
class MyApp extends StatefulWidget {
// Store initial locale settings here, they are unchanged
final String initialDefaultSystemLocale;
final List<Locale> initialSystemLocales;
MyApp(this.initialDefaultSystemLocale, this.initialSystemLocales);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
// Store dynamic changeable locale settings here, they change with the system changes
String currentDefaultSystemLocale;
List<Locale> currentSystemLocales;
// Here we read the current locale values
void setCurrentValues() {
currentSystemLocales = WidgetsBinding.instance.window.locales;
currentDefaultSystemLocale = Platform.localeName;
}
@override
void initState() {
// This is run when the widget is first time initialized
WidgetsBinding.instance.addObserver(this); // Subscribe to changes
setCurrentValues();
super.initState();
}
@override
void didChangeLocales(List<Locale> locale) {
// This is run when system locales are changed
super.didChangeLocales(locale);
// Update state with the new values and redraw controls
setState(() {
setCurrentValues();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('Initial system default locale: ${widget.initialDefaultSystemLocale}.'),
Text('Initial language code: ${widget.initialDefaultSystemLocale.split('_')[0]}, country code: ${widget.initialDefaultSystemLocale.split('_')[1]}.'),
Text('Initial system locales:'),
for (var locale in widget.initialSystemLocales) Text(locale.toString()),
Text(''),
Text('Current system default locale: ${currentDefaultSystemLocale}.'),
Text('Current system locales:'),
for (var locale in currentSystemLocales) Text(locale.toString()),
Text(''),
Text('Selected application locale: ${Localizations.localeOf(context).toString()}.'),
Text(''),
Text('Current date: ${Localizations.of<MaterialLocalizations>(context, MaterialLocalizations).formatFullDate(DateTime.now())}.'),
Text('Current time zone: ${DateTime.now().timeZoneName} (offset ${DateTime.now().timeZoneOffset}).'),
],
),
);
}
}
MaterialApp
小部件将应用支持的语言环境列表与系统传递的用户偏好列表进行比较,并选择最合适的语言环境。假设我们有以下系统语言环境列表(en_US,en_GB,ru_RU):** 点击缩略图查看完整截图。
我们的应用程序启动时将看起来像这样:
我们可以看到初始值和当前值明显相同。应用程序选择en
作为其当前语言环境。en
区域设置为当前区域设置,因为它是与en_US
和en_GB
区域设置最接近的匹配项。https://flutter.io/tutorials/internationalization/#tracking-locale
在Flutter中,通过
Localizations.localeOf(context)
可以获取countryCode
和languageCode
。
https://docs.flutter.io/flutter/dart-ui/Locale-class.html
时区应该可以使用以下方法获得(未尝试):
DateTime.now().timeZoneName
https://docs.flutter.io/flutter/dart-core/DateTime-class.html
Localizations.localeOf(context)
并不适用于所有情况:它返回的是 _当前上下文的语言环境_,该语言环境源自系统的语言设置,但已经被解析为 supportedLocales
中的某个语言环境。这是传递给 MaterialApp
或 WidgetsApp
的参数,默认只有 [en_US]
。使用 WidgetsBinding.instance.window.locale
可以获取原始的语言环境信息。 - Thomas你可以使用
import 'dart:io' show Platform;
String languageCode = Platform.localeName.split('_')[0];
String countryCode = Platform.localeName.split('_')[1];
Platform.localeName
仅返回语言代码而没有国家代码(例如“en”)时,这将抛出RangeError。 - mrcendre试一下:
import 'dart:ui' as ui;
......
@override
Widget build(BuildContext context) {
// get system language code
_sysLng = ui.window.locale.languageCode;
...
String deviceLanguage= Platform.localeName.substring(0,2);
它只会给你"en"或"tr"等...
如果你想要国家代码,请使用以下内容;
String deviceCountry= Platform.localeName.substring(3,5);
它仅提供给您“US”或“TR”等...
Add the package as a dependency to your pubspec.yaml file
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
Import the flutter_localizations library and specify localizationsDelegates and supportedLocales for MaterialApp
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English, no country code
const Locale('es', ''), // Spanish, no country code
// ... other locales the app supports
],
// ...
)
For iOS only: open the ios module and add the supported languages under localization
获取当前语言环境
Locale myLocale = Localizations.localeOf(context);
对于时区,其他答案会给出缩写如“CET”,“MSK”等以及GMT偏移量。
要以Europe/Paris
格式获取设备的时区,请使用flutter_native_timezone包:
final String currentTimeZone = await FlutterNativeTimezone.getLocalTimezone();
import 'package:flutter/material.dart';
// or import 'package:flutter/widgets.dart';
final List<Locale> systemLocales =
WidgetsBinding.instance.platformDispatcher.locales;
print(systemLocales);
例如,此将从 chrome://settings/languages 返回首选语言列表。
import 'package:flutter/material.dart';
// or import 'package:flutter/widgets.dart';
final Locale appLocale = Localizations.localeOf(context);
print(appLocale);
import 'package:easy_localization/easy_localization.dart';
Platform.localeName.toLocale().languageCode
Platform.localeName.toLocale().countryCode
import 'dart:io';
String getDeviceLanguage(){
return Platform.localeName.contains("_")
? Platform.localeName.split("_")[0]
: Platform.localeName;
}
String deviceLanguage= Platform.localeName.substring(0,2);
WidgetsBinding.instance.platformDispatcher.locales
来获取系统区域设置列表,因为window
已被弃用。 - undefined