diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 909a01fc72..35d3039eda 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -3272,29 +3272,28 @@ abstract class Element extends DiagnosticableTree implements BuildContext { @mustCallSuper void didChangeDependencies() { assert(_active); // otherwise markNeedsBuild is a no-op - _debugCheckOwnerBuildTargetExists('didChangeDependencies'); + assert(_debugCheckOwnerBuildTargetExists('didChangeDependencies')); markNeedsBuild(); } - void _debugCheckOwnerBuildTargetExists(String methodName) { + bool _debugCheckOwnerBuildTargetExists(String methodName) { assert(() { if (owner._debugCurrentBuildTarget == null) { throw new FlutterError( - '$methodName for ${widget.runtimeType} was called at an ' - 'inappropriate time.\n' - '\n' - 'It may only be called while the widgets are being built. A possible ' - 'cause of this error is when $methodName is called during ' - 'one of:\n' - '\n' - ' * network I/O event\n' - ' * file I/O event\n' - ' * timer\n' - ' * microtask (caused by Future.then, async/await, scheduleMicrotask)' + '$methodName for ${widget.runtimeType} was called at an ' + 'inappropriate time.\n' + 'It may only be called while the widgets are being built. A possible ' + 'cause of this error is when $methodName is called during ' + 'one of:\n' + ' * network I/O event\n' + ' * file I/O event\n' + ' * timer\n' + ' * microtask (caused by Future.then, async/await, scheduleMicrotask)' ); } return true; - }); + }()); + return true; } /// Returns a description of what caused this element to be created. @@ -3942,7 +3941,7 @@ class InheritedElement extends ProxyElement { /// by first obtaining their [InheritedElement] using /// [BuildContext.ancestorInheritedElementForWidgetOfExactType]. void dispatchDidChangeDependencies() { - _debugCheckOwnerBuildTargetExists('dispatchDidChangeDependencies'); + assert(_debugCheckOwnerBuildTargetExists('dispatchDidChangeDependencies')); for (Element dependent in _dependents) { assert(() { // check that it really is our descendant diff --git a/packages/flutter/lib/src/widgets/localizations.dart b/packages/flutter/lib/src/widgets/localizations.dart index d238c4e39f..bfabeb26dd 100644 --- a/packages/flutter/lib/src/widgets/localizations.dart +++ b/packages/flutter/lib/src/widgets/localizations.dart @@ -206,23 +206,20 @@ class _LocalizationsScope extends InheritedWidget { Key key, @required this.locale, @required this.localizationsState, - @required this.loadGeneration, + @required this.typeToResources, Widget child, }) : super(key: key, child: child) { assert(localizationsState != null); + assert(typeToResources != null); } final Locale locale; final _LocalizationsState localizationsState; - - /// A monotonically increasing number that changes after localizations - /// delegates have finished loading new data. When this number changes, it - /// triggers inherited widget notifications. - final int loadGeneration; + final Map typeToResources; @override bool updateShouldNotify(_LocalizationsScope old) { - return loadGeneration != old.loadGeneration; + return typeToResources != old.typeToResources; } } @@ -445,11 +442,6 @@ class _LocalizationsState extends State { final GlobalKey _localizedResourcesScopeKey = new GlobalKey(); Map _typeToResources = {}; - /// A monotonically increasing number that increases after localizations - /// delegates have finished loading new data, triggering inherited widget - /// notifications. - int _loadGeneration = 0; - Locale get locale => _locale; Locale _locale; @@ -513,7 +505,6 @@ class _LocalizationsState extends State { setState(() { _typeToResources = value; _locale = locale; - _loadGeneration += 1; }); }); } @@ -539,7 +530,7 @@ class _LocalizationsState extends State { key: _localizedResourcesScopeKey, locale: _locale, localizationsState: this, - loadGeneration: _loadGeneration, + typeToResources: _typeToResources, child: new Directionality( textDirection: _textDirection, child: widget.child, diff --git a/packages/flutter/test/widgets/localizations_test.dart b/packages/flutter/test/widgets/localizations_test.dart index 5fac194fa5..489947ab78 100644 --- a/packages/flutter/test/widgets/localizations_test.dart +++ b/packages/flutter/test/widgets/localizations_test.dart @@ -159,6 +159,23 @@ Widget buildFrame({ ); } +class SyncLoadTest extends StatefulWidget { + const SyncLoadTest(); + + @override + SyncLoadTestState createState() => new SyncLoadTestState(); +} + +class SyncLoadTestState extends State { + @override + Widget build(BuildContext context) { + return new Text( + TestLocalizations.of(context).message, + textDirection: TextDirection.rtl, + ); + } +} + void main() { testWidgets('Localizations.localeFor in a WidgetsApp with system locale', (WidgetTester tester) async { BuildContext pageContext; @@ -205,27 +222,27 @@ void main() { }); testWidgets('Synchronously loaded localizations in a WidgetsApp', (WidgetTester tester) async { - BuildContext pageContext; - await tester.pumpWidget( - buildFrame( - delegates: >[ - new SyncTestLocalizationsDelegate() - ], - buildContent: (BuildContext context) { - pageContext = context; - return new Text(TestLocalizations.of(context).message); - } - ) - ); + final List> delegates = >[ + new SyncTestLocalizationsDelegate(), + const DefaultWidgetsLocalizationsDelegate(), + ]; - expect(TestLocalizations.of(pageContext), isNotNull); + Future pumpTest(Locale locale) async { + await tester.pumpWidget(new Localizations( + locale: locale, + delegates: delegates, + child: const SyncLoadTest(), + )); + } + + await pumpTest(const Locale('en', 'US')); expect(find.text('en_US'), findsOneWidget); - await tester.binding.setLocale('en', 'GB'); + await pumpTest(const Locale('en', 'GB')); await tester.pump(); expect(find.text('en_GB'), findsOneWidget); - await tester.binding.setLocale('en', 'US'); + await pumpTest(const Locale('en', 'US')); await tester.pump(); expect(find.text('en_US'), findsOneWidget); });