Unverified Commit 06cc1d9e authored by Hans Muller's avatar Hans Muller Committed by GitHub

Resolve MaterialApp.locale, WidgetsApp.locale per supportedLocales (#23707)

parent 7217999a
......@@ -29,9 +29,13 @@ export 'dart:ui' show Locale;
/// [Localizations] object when the app starts and when user changes the default
/// locale for the device.
///
/// The `locale` is the device's locale when the app started, or the device
/// locale the user selected after the app was started. The `supportedLocales`
/// parameter is just the value of [WidgetsApp.supportedLocales].
/// This callback is also used if the app is created with a specific locale using
/// the [new WidgetsApp] `locale` parameter.
///
/// The `locale` is either the value of [WidgetsApp.locale], or the device's
/// locale when the app started, or the device locale the user selected after
/// the app was started. The `supportedLocales` parameter is the value of
/// [WidgetsApp.supportedLocales].
typedef LocaleResolutionCallback = Locale Function(Locale locale, Iterable<Locale> supportedLocales);
/// The signature of [WidgetsApp.onGenerateTitle].
......@@ -408,10 +412,22 @@ class WidgetsApp extends StatefulWidget {
final Color color;
/// {@template flutter.widgets.widgetsApp.locale}
/// The initial locale for this app's [Localizations] widget.
/// The initial locale for this app's [Localizations] widget is based
/// on this value.
///
/// If the 'locale' is null then the system's locale value is used.
///
/// If the 'locale' is null the system's locale value is used.
/// The value of [Localizations.locale] will equal this locale if
/// it matches one of the [supportedLocales]. Otherwise it will be
/// the first [supportedLocale].
/// {@endtemplate}
///
/// See also:
///
/// * [localeResolutionCallback], which can override the default
/// [supportedLocales] matching algorithm.
/// * [localizationsDelegates], which collectively define all of the localized
/// resources used by this app.
final Locale locale;
/// {@template flutter.widgets.widgetsApp.localizationsDelegates}
......@@ -467,10 +483,8 @@ class WidgetsApp extends StatefulWidget {
///
/// * [MaterialApp.supportedLocales], which sets the `supportedLocales`
/// of the [WidgetsApp] it creates.
///
/// * [localeResolutionCallback], an app callback that resolves the app's locale
/// when the device's locale changes.
///
/// * [localizationsDelegates], which collectively define all of the localized
/// resources used by this app.
final Iterable<Locale> supportedLocales;
......@@ -863,7 +877,9 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
return MediaQuery(
data: MediaQueryData.fromWindow(ui.window),
child: Localizations(
locale: widget.locale ?? _locale,
locale: widget.locale != null
? _resolveLocale(widget.locale, widget.supportedLocales)
: _locale,
delegates: _localizationsDelegates.toList(),
child: title,
),
......
......@@ -107,6 +107,7 @@ void main() {
Widget buildLocaleFrame(Locale locale) {
return buildFrame(
locale: locale,
supportedLocales: <Locale>[locale],
buildContent: (BuildContext context) {
return Localizations.override(
context: context,
......
......@@ -17,6 +17,7 @@ class _TimePickerLauncher extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
locale: locale,
supportedLocales: <Locale>[locale],
localizationsDelegates: GlobalMaterialLocalizations.delegates,
home: Material(
child: Center(
......
......@@ -695,4 +695,54 @@ void main() {
await tester.pumpAndSettle();
expect(find.text('en_US zh_CN'), findsOneWidget);
});
testWidgets('WidgetsApp.locale is resolved against supportedLocales', (WidgetTester tester) async {
// app locale matches a supportedLocale
await tester.pumpWidget(
buildFrame(
supportedLocales: const <Locale>[
Locale('zh', 'CN'),
Locale('en', 'US'),
],
locale: const Locale('en', 'US'),
buildContent: (BuildContext context) {
return Text(Localizations.localeOf(context).toString());
}
)
);
await tester.pumpAndSettle();
expect(find.text('en_US'), findsOneWidget);
// app locale matches a supportedLocale's language
await tester.pumpWidget(
buildFrame(
supportedLocales: const <Locale>[
Locale('zh', 'CN'),
Locale('en', 'GB'),
],
locale: const Locale('en', 'US'),
buildContent: (BuildContext context) {
return Text(Localizations.localeOf(context).toString());
}
)
);
await tester.pumpAndSettle();
expect(find.text('en_GB'), findsOneWidget);
// app locale matches no supportedLocale
await tester.pumpWidget(
buildFrame(
supportedLocales: const <Locale>[
Locale('zh', 'CN'),
Locale('en', 'US'),
],
locale: const Locale('ab', 'CD'),
buildContent: (BuildContext context) {
return Text(Localizations.localeOf(context).toString());
}
)
);
await tester.pumpAndSettle();
expect(find.text('zh_CN'), findsOneWidget);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment