diff --git a/packages/flutter/lib/src/widgets/app.dart b/packages/flutter/lib/src/widgets/app.dart index 29962da064..a4ec5b521a 100644 --- a/packages/flutter/lib/src/widgets/app.dart +++ b/packages/flutter/lib/src/widgets/app.dart @@ -28,9 +28,7 @@ class _WidgetsLocalizationsDelegate extends LocalizationsDelegate load(Locale locale) { - return new SynchronousFuture(const WidgetsLocalizations()); - } + Future load(Locale locale) => DefaultWidgetsLocalizations.load(locale); @override bool shouldReload(_WidgetsLocalizationsDelegate old) => false; diff --git a/packages/flutter/lib/src/widgets/localizations.dart b/packages/flutter/lib/src/widgets/localizations.dart index 5ed7d603f2..535d289870 100644 --- a/packages/flutter/lib/src/widgets/localizations.dart +++ b/packages/flutter/lib/src/widgets/localizations.dart @@ -114,20 +114,13 @@ abstract class LocalizationsDelegate { /// In particular, this maps locales to a specific [Directionality] using the /// [textDirection] property. /// -/// This class provides a default placeholder implementation that returns -/// hard-coded American English values. -class WidgetsLocalizations { - /// Create a placeholder object for the localized resources of the lowest - /// levels of the Flutter framework which only provides values for American - /// English. - const WidgetsLocalizations(); - - /// The locale for which the values of this class's localized resources - /// have been translated. - Locale get locale => const Locale('en', 'US'); - +/// See also: +/// +/// * [DefaultWidgetsLocalizations], which implements this interface and +/// supports a variety of locales. +abstract class WidgetsLocalizations { /// The reading direction for text in this locale. - TextDirection get textDirection => TextDirection.ltr; + TextDirection get textDirection; /// The `WidgetsLocalizations` from the closest [Localizations] instance /// that encloses the given context. @@ -146,6 +139,42 @@ class WidgetsLocalizations { } } +/// Localized values for widgets. +class DefaultWidgetsLocalizations implements WidgetsLocalizations { + DefaultWidgetsLocalizations(this.locale) { + final String language = locale.languageCode.toLowerCase(); + _textDirection = _rtlLanguages.contains(language) ? TextDirection.rtl : TextDirection.ltr; + } + + // See http://en.wikipedia.org/wiki/Right-to-left + static const List _rtlLanguages = const [ + 'ar', // Arabic + 'dv', // Dhivehi + 'fa', // Farsi + 'he', // Hebrew + 'ps', // Pashto + 'sd', // Sindhi + 'ur', // Urdu + ]; + + /// The locale for which the values of this class's localized resources + /// have been translated. + final Locale locale; + + @override + TextDirection get textDirection => _textDirection; + TextDirection _textDirection; + + /// Creates an object that provides localized resource values for the + /// lowest levels of the Flutter framework. + /// + /// This method is typically used to create a [LocalizationsDelegate]. + /// The [WidgetsApp] does so by default. + static Future load(Locale locale) { + return new SynchronousFuture(new DefaultWidgetsLocalizations(locale)); + } +} + class _LocalizationsScope extends InheritedWidget { _LocalizationsScope ({ Key key, diff --git a/packages/flutter/test/widgets/localizations_test.dart b/packages/flutter/test/widgets/localizations_test.dart index c08b6eea6c..18974fa491 100644 --- a/packages/flutter/test/widgets/localizations_test.dart +++ b/packages/flutter/test/widgets/localizations_test.dart @@ -417,6 +417,26 @@ void main() { expect(modifiedDelegate.shouldReloadValues, [true]); }); + testWidgets('Directionality tracks system locale', (WidgetTester tester) async { + BuildContext pageContext; + + await tester.pumpWidget( + buildFrame( + buildContent: (BuildContext context) { + pageContext = context; + return const Text('Hello World'); + } + ) + ); + + await tester.binding.setLocale('en', 'GB'); + await tester.pump(); + expect(Directionality.of(pageContext), TextDirection.ltr); + + await tester.binding.setLocale('ar', 'EG'); + await tester.pump(); + expect(Directionality.of(pageContext), TextDirection.rtl); + }); } // Same as _WidgetsLocalizationsDelegate in widgets/app.dart @@ -424,9 +444,7 @@ class DefaultWidgetsLocalizationsDelegate extends LocalizationsDelegate load(Locale locale) { - return new SynchronousFuture(const WidgetsLocalizations()); - } + Future load(Locale locale) => DefaultWidgetsLocalizations.load(locale); @override bool shouldReload(DefaultWidgetsLocalizationsDelegate old) => false;