Skip to content

Commit 872c9d7

Browse files
authored
Add maybeLocaleOf to Localizations (flutter#68911)
1 parent 9383ec7 commit 872c9d7

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

packages/flutter/lib/src/widgets/basic.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5541,7 +5541,7 @@ class RichText extends MultiChildRenderObjectWidget {
55415541
strutStyle: strutStyle,
55425542
textWidthBasis: textWidthBasis,
55435543
textHeightBehavior: textHeightBehavior,
5544-
locale: locale ?? Localizations.localeOf(context, nullOk: true),
5544+
locale: locale ?? Localizations.maybeLocaleOf(context),
55455545
);
55465546
}
55475547

@@ -5559,7 +5559,7 @@ class RichText extends MultiChildRenderObjectWidget {
55595559
..strutStyle = strutStyle
55605560
..textWidthBasis = textWidthBasis
55615561
..textHeightBehavior = textHeightBehavior
5562-
..locale = locale ?? Localizations.localeOf(context, nullOk: true);
5562+
..locale = locale ?? Localizations.maybeLocaleOf(context);
55635563
}
55645564

55655565
@override

packages/flutter/lib/src/widgets/editable_text.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,7 +2779,7 @@ class _Editable extends LeafRenderObjectWidget {
27792779
textScaleFactor: textScaleFactor,
27802780
textAlign: textAlign,
27812781
textDirection: textDirection,
2782-
locale: locale ?? Localizations.localeOf(context, nullOk: true),
2782+
locale: locale ?? Localizations.maybeLocaleOf(context),
27832783
selection: value.selection,
27842784
offset: offset,
27852785
onSelectionChanged: onSelectionChanged,
@@ -2824,7 +2824,7 @@ class _Editable extends LeafRenderObjectWidget {
28242824
..textScaleFactor = textScaleFactor
28252825
..textAlign = textAlign
28262826
..textDirection = textDirection
2827-
..locale = locale ?? Localizations.localeOf(context, nullOk: true)
2827+
..locale = locale ?? Localizations.maybeLocaleOf(context)
28282828
..selection = value.selection
28292829
..offset = offset
28302830
..onSelectionChanged = onSelectionChanged

packages/flutter/lib/src/widgets/image.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ImageConfiguration createLocalImageConfiguration(BuildContext context, { Size? s
5151
return ImageConfiguration(
5252
bundle: DefaultAssetBundle.of(context),
5353
devicePixelRatio: MediaQuery.maybeOf(context)?.devicePixelRatio ?? 1.0,
54-
locale: Localizations.localeOf(context, nullOk: true),
54+
locale: Localizations.maybeLocaleOf(context),
5555
textDirection: Directionality.maybeOf(context),
5656
size: size,
5757
platform: defaultTargetPlatform,

packages/flutter/lib/src/widgets/localizations.dart

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,14 +416,38 @@ class Localizations extends StatefulWidget {
416416
/// true, in which case it returns null.
417417
static Locale? localeOf(BuildContext context, { bool nullOk = false }) {
418418
assert(context != null);
419-
assert(nullOk != null);
420419
final _LocalizationsScope? scope = context.dependOnInheritedWidgetOfExactType<_LocalizationsScope>();
421420
if (nullOk && scope == null)
422421
return null;
423-
assert(scope != null, 'a Localizations ancestor was not found');
422+
assert(() {
423+
if (scope == null) {
424+
throw FlutterError(
425+
'Requested the Locale of a context that does not include a Localizations ancestor.\n'
426+
'To request the Locale, the context used to retrieve the Localizations widget must '
427+
'be that of a widget that is a descendant of a Localizations widget.'
428+
);
429+
}
430+
if (!nullOk && scope.localizationsState.locale == null) {
431+
throw FlutterError(
432+
'Localizations.localeOf found a Localizations widget that had a unexpected null locale.\n'
433+
);
434+
}
435+
return true;
436+
}());
424437
return scope!.localizationsState.locale;
425438
}
426439

440+
/// The locale of the Localizations widget for the widget tree that
441+
/// corresponds to [BuildContext] `context`.
442+
///
443+
/// If no [Localizations] widget is in scope then this function will return
444+
/// null. Equivalent to calling [localeOf] with `nullOk` set to true.
445+
static Locale? maybeLocaleOf(BuildContext context) {
446+
assert(context != null);
447+
final _LocalizationsScope? scope = context.dependOnInheritedWidgetOfExactType<_LocalizationsScope>();
448+
return scope?.localizationsState.locale;
449+
}
450+
427451
// There doesn't appear to be a need to make this public. See the
428452
// Localizations.override factory constructor.
429453
static List<LocalizationsDelegate<dynamic>> _delegatesOf(BuildContext context) {

packages/flutter/test/widgets/localizations_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@ void main() {
3434
await tester.pump();
3535
expect(find.text('loaded'), findsOneWidget);
3636
});
37+
38+
testWidgets('Localizations.localeOf throws when no localizations exist', (WidgetTester tester) async {
39+
final GlobalKey contextKey = GlobalKey(debugLabel: 'Test Key');
40+
await tester.pumpWidget(Container(key: contextKey));
41+
42+
expect(() => Localizations.localeOf(contextKey.currentContext!), throwsA(isAssertionError.having(
43+
(AssertionError e) => e.message,
44+
'message',
45+
contains('does not include a Localizations ancestor'),
46+
)));
47+
});
48+
49+
testWidgets('Localizations.maybeLocaleOf returns null when no localizations exist', (WidgetTester tester) async {
50+
final GlobalKey contextKey = GlobalKey(debugLabel: 'Test Key');
51+
await tester.pumpWidget(Container(key: contextKey));
52+
53+
expect(Localizations.maybeLocaleOf(contextKey.currentContext!), isNull);
54+
});
3755
}
3856

3957
class FakeLocalizationsDelegate extends LocalizationsDelegate<String> {

0 commit comments

Comments
 (0)