Skip to content

Commit e55dedc

Browse files
shivanuj13anuj.kumar
authored andcommitted
Fixed changing supportedLocales fails to update the locale (flutter#178526)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> Recompute the resolved locale in LocalizationsResolver.update(...) and notify listeners only when the resolved locale actually changes. Previously, updating WidgetsApp.supportedLocales did not always propagate to the app locale because the resolver did not re-resolve and notify listeners. This change fixes that bug and adds unit tests. Fixes [https://github.com/flutter/flutter/issues/117210](https://github.com/flutter/flutter/issues/117210) ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: anuj.kumar <anuj.kumar@powerup.money>
1 parent bc8ee64 commit e55dedc

File tree

3 files changed

+82
-10
lines changed

3 files changed

+82
-10
lines changed

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,14 +1650,24 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
16501650
supportedLocales: widget.supportedLocales,
16511651
);
16521652

1653-
void _updateLocalizations({WidgetsApp? oldWidget}) {
1654-
_localizationsResolver.update(
1655-
locale: widget.locale,
1656-
localeListResolutionCallback: widget.localeListResolutionCallback,
1657-
localeResolutionCallback: widget.localeResolutionCallback,
1658-
supportedLocales: widget.supportedLocales,
1659-
localizationsDelegates: widget.localizationsDelegates,
1660-
);
1653+
bool _shouldUpdateLocalizations(WidgetsApp oldWidget) {
1654+
return widget.locale != oldWidget.locale ||
1655+
widget.localeListResolutionCallback != oldWidget.localeListResolutionCallback ||
1656+
widget.localeResolutionCallback != oldWidget.localeResolutionCallback ||
1657+
widget.supportedLocales != oldWidget.supportedLocales ||
1658+
widget.localizationsDelegates != oldWidget.localizationsDelegates;
1659+
}
1660+
1661+
void _updateLocalizations({required WidgetsApp oldWidget}) {
1662+
if (_shouldUpdateLocalizations(oldWidget)) {
1663+
_localizationsResolver.update(
1664+
locale: widget.locale,
1665+
localeListResolutionCallback: widget.localeListResolutionCallback,
1666+
localeResolutionCallback: widget.localeResolutionCallback,
1667+
localizationsDelegates: widget.localizationsDelegates,
1668+
supportedLocales: widget.supportedLocales,
1669+
);
1670+
}
16611671
}
16621672

16631673
// BUILDER

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,10 @@ class LocalizationsResolver extends ChangeNotifier with WidgetsBindingObserver {
808808
_localeListResolutionCallback = localeListResolutionCallback;
809809
_localeResolutionCallback = localeResolutionCallback;
810810
_localizationsDelegates = localizationsDelegates;
811-
_supportedLocales = supportedLocales;
811+
if (_supportedLocales != supportedLocales) {
812+
_supportedLocales = supportedLocales;
813+
_updateResolvedLocale(WidgetsBinding.instance.platformDispatcher.locales);
814+
}
812815
}
813816

814817
/// The currently resolved [Locale] based on the current platform locale and
@@ -867,7 +870,17 @@ class LocalizationsResolver extends ChangeNotifier with WidgetsBindingObserver {
867870

868871
@override
869872
void didChangeLocales(List<Locale>? locales) {
870-
final Locale newLocale = _resolveLocales(locales, supportedLocales);
873+
_updateResolvedLocale(locales);
874+
}
875+
876+
/// Recompute the resolved locale based on [preferredLocales] and
877+
/// [supportedLocales], update the resolved locale, and notify listeners
878+
/// only if the resolved locale changed.
879+
///
880+
/// This method is called from both [update] (when locale resolution
881+
/// parameters change) and [didChangeLocales] (when system locales change).
882+
void _updateResolvedLocale(List<Locale>? preferredLocales) {
883+
final Locale newLocale = _resolveLocales(preferredLocales, supportedLocales);
871884
if (newLocale != _resolvedLocale) {
872885
_resolvedLocale = newLocale;
873886
notifyListeners();

packages/flutter/test/widgets/localizations_test.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,55 @@ void main() {
106106
expect(Localizations.maybeLocaleOf(contextKey.currentContext!), isNull);
107107
});
108108

109+
testWidgets('LocalizationsResolver.update notifies listeners when supportedLocales changes', (
110+
WidgetTester tester,
111+
) async {
112+
final LocalizationsResolver resolver = LocalizationsResolver(
113+
supportedLocales: <Locale>[const Locale('en')],
114+
);
115+
116+
bool notified = false;
117+
resolver.addListener(() {
118+
notified = true;
119+
});
120+
121+
resolver.update(
122+
locale: null,
123+
localeListResolutionCallback: null,
124+
localeResolutionCallback: null,
125+
localizationsDelegates: null,
126+
supportedLocales: <Locale>[const Locale('de')],
127+
);
128+
129+
expect(notified, isTrue);
130+
resolver.dispose();
131+
});
132+
133+
testWidgets('LocalizationsResolver.update does not notify when resolved locale unchanged', (
134+
WidgetTester tester,
135+
) async {
136+
final LocalizationsResolver resolver = LocalizationsResolver(
137+
supportedLocales: <Locale>[const Locale('en'), const Locale('de')],
138+
);
139+
140+
bool notified = false;
141+
resolver.addListener(() {
142+
notified = true;
143+
});
144+
145+
// Update with the same effective supportedLocales shouldn't change resolved locale.
146+
resolver.update(
147+
locale: null,
148+
localeListResolutionCallback: null,
149+
localeResolutionCallback: null,
150+
localizationsDelegates: null,
151+
supportedLocales: <Locale>[const Locale('en'), const Locale('de')],
152+
);
153+
154+
expect(notified, isFalse);
155+
resolver.dispose();
156+
});
157+
109158
group('Semantics', () {
110159
testWidgets('set locale semantics', (WidgetTester tester) async {
111160
await tester.pumpWidget(

0 commit comments

Comments
 (0)