Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
796c5439
Commit
796c5439
authored
Oct 20, 2017
by
Hans Muller
Committed by
GitHub
Oct 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Language-specific LocalizationDelegates (#12645)
parent
a554401e
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
152 additions
and
8 deletions
+152
-8
main.dart
examples/stocks/lib/main.dart
+3
-0
material_localizations.dart
...ages/flutter/lib/src/material/material_localizations.dart
+3
-0
localizations.dart
packages/flutter/lib/src/widgets/localizations.dart
+14
-2
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+6
-0
material_localizations.dart
...flutter_localizations/lib/src/material_localizations.dart
+21
-0
widgets_localizations.dart
.../flutter_localizations/lib/src/widgets_localizations.dart
+3
-0
basics_test.dart
packages/flutter_localizations/test/basics_test.dart
+3
-0
override_test.dart
packages/flutter_localizations/test/override_test.dart
+84
-6
widgets_test.dart
packages/flutter_localizations/test/widgets_test.dart
+15
-0
No files found.
examples/stocks/lib/main.dart
View file @
796c5439
...
@@ -26,6 +26,9 @@ class _StocksLocalizationsDelegate extends LocalizationsDelegate<StockStrings> {
...
@@ -26,6 +26,9 @@ class _StocksLocalizationsDelegate extends LocalizationsDelegate<StockStrings> {
@override
@override
Future
<
StockStrings
>
load
(
Locale
locale
)
=>
StockStrings
.
load
(
locale
);
Future
<
StockStrings
>
load
(
Locale
locale
)
=>
StockStrings
.
load
(
locale
);
@override
bool
isSupported
(
Locale
locale
)
=>
locale
.
languageCode
==
'es'
||
locale
.
languageCode
==
'en'
;
@override
@override
bool
shouldReload
(
_StocksLocalizationsDelegate
old
)
=>
false
;
bool
shouldReload
(
_StocksLocalizationsDelegate
old
)
=>
false
;
}
}
...
...
packages/flutter/lib/src/material/material_localizations.dart
View file @
796c5439
...
@@ -187,6 +187,9 @@ abstract class MaterialLocalizations {
...
@@ -187,6 +187,9 @@ abstract class MaterialLocalizations {
class
_MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
class
_MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
const
_MaterialLocalizationsDelegate
();
const
_MaterialLocalizationsDelegate
();
@override
bool
isSupported
(
Locale
locale
)
=>
locale
.
languageCode
==
'en'
;
@override
@override
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
DefaultMaterialLocalizations
.
load
(
locale
);
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
DefaultMaterialLocalizations
.
load
(
locale
);
...
...
packages/flutter/lib/src/widgets/localizations.dart
View file @
796c5439
...
@@ -42,11 +42,12 @@ Future<Map<Type, dynamic>> _loadAll(Locale locale, Iterable<LocalizationsDelegat
...
@@ -42,11 +42,12 @@ Future<Map<Type, dynamic>> _loadAll(Locale locale, Iterable<LocalizationsDelegat
final
Map
<
Type
,
dynamic
>
output
=
<
Type
,
dynamic
>{};
final
Map
<
Type
,
dynamic
>
output
=
<
Type
,
dynamic
>{};
List
<
_Pending
>
pendingList
;
List
<
_Pending
>
pendingList
;
// Only load the first delegate for each delgate type.
// Only load the first delegate for each delegate type that supports
// locale.languageCode.
final
Set
<
Type
>
types
=
new
Set
<
Type
>();
final
Set
<
Type
>
types
=
new
Set
<
Type
>();
final
List
<
LocalizationsDelegate
<
dynamic
>>
delegates
=
<
LocalizationsDelegate
<
dynamic
>>[];
final
List
<
LocalizationsDelegate
<
dynamic
>>
delegates
=
<
LocalizationsDelegate
<
dynamic
>>[];
for
(
LocalizationsDelegate
<
dynamic
>
delegate
in
allDelegates
)
{
for
(
LocalizationsDelegate
<
dynamic
>
delegate
in
allDelegates
)
{
if
(!
types
.
contains
(
delegate
.
type
))
{
if
(!
types
.
contains
(
delegate
.
type
)
&&
delegate
.
isSupported
(
locale
)
)
{
types
.
add
(
delegate
.
type
);
types
.
add
(
delegate
.
type
);
delegates
.
add
(
delegate
);
delegates
.
add
(
delegate
);
}
}
...
@@ -97,6 +98,12 @@ abstract class LocalizationsDelegate<T> {
...
@@ -97,6 +98,12 @@ abstract class LocalizationsDelegate<T> {
/// const constructors so that they can be used in const expressions.
/// const constructors so that they can be used in const expressions.
const
LocalizationsDelegate
();
const
LocalizationsDelegate
();
/// Whether resources for the given locale can be loaded by this delegate.
///
/// Return true if the instance of `T` loaded by this delegate's [load]
/// method supports the given `locale`'s language.
bool
isSupported
(
Locale
locale
);
/// Start loading the resources for `locale`. The returned future completes
/// Start loading the resources for `locale`. The returned future completes
/// when the resources have finished loading.
/// when the resources have finished loading.
///
///
...
@@ -164,6 +171,11 @@ abstract class WidgetsLocalizations {
...
@@ -164,6 +171,11 @@ abstract class WidgetsLocalizations {
class
_WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
class
_WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
const
_WidgetsLocalizationsDelegate
();
const
_WidgetsLocalizationsDelegate
();
// This is convenient simplification. It would be more correct test if the locale's
// text-direction is LTR.
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
DefaultWidgetsLocalizations
.
load
(
locale
);
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
DefaultWidgetsLocalizations
.
load
(
locale
);
...
...
packages/flutter/test/material/text_field_test.dart
View file @
796c5439
...
@@ -28,6 +28,9 @@ class MockClipboard {
...
@@ -28,6 +28,9 @@ class MockClipboard {
}
}
class
MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
class
MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
DefaultMaterialLocalizations
.
load
(
locale
);
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
DefaultMaterialLocalizations
.
load
(
locale
);
...
@@ -36,6 +39,9 @@ class MaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocali
...
@@ -36,6 +39,9 @@ class MaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocali
}
}
class
WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
class
WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
DefaultWidgetsLocalizations
.
load
(
locale
);
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
DefaultWidgetsLocalizations
.
load
(
locale
);
...
...
packages/flutter_localizations/lib/src/material_localizations.dart
View file @
796c5439
...
@@ -423,6 +423,27 @@ void _loadDateIntlDataIfNotLoaded() {
...
@@ -423,6 +423,27 @@ void _loadDateIntlDataIfNotLoaded() {
class
_MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
class
_MaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
const
_MaterialLocalizationsDelegate
();
const
_MaterialLocalizationsDelegate
();
static
const
List
<
String
>
_supportedLanguages
=
const
<
String
>[
'ar'
,
// Arabic
'de'
,
// German
'en'
,
// English
'es'
,
// Spanish
'fa'
,
// Farsi
'fr'
,
// French
'he'
,
// Hebrew
'it'
,
// Italian
'ja'
,
// Japanese
'ps'
,
// Pashto
'pt'
,
// Portugese
'ru'
,
// Russian
'sd'
,
// Sindhi
'ur'
,
// Urdu
'zh'
,
// Simplified Chinese
];
@override
bool
isSupported
(
Locale
locale
)
=>
_supportedLanguages
.
contains
(
locale
.
languageCode
);
@override
@override
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
GlobalMaterialLocalizations
.
load
(
locale
);
Future
<
MaterialLocalizations
>
load
(
Locale
locale
)
=>
GlobalMaterialLocalizations
.
load
(
locale
);
...
...
packages/flutter_localizations/lib/src/widgets_localizations.dart
View file @
796c5439
...
@@ -67,6 +67,9 @@ class GlobalWidgetsLocalizations implements WidgetsLocalizations {
...
@@ -67,6 +67,9 @@ class GlobalWidgetsLocalizations implements WidgetsLocalizations {
class
_WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
class
_WidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
const
_WidgetsLocalizationsDelegate
();
const
_WidgetsLocalizationsDelegate
();
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
GlobalWidgetsLocalizations
.
load
(
locale
);
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
=>
GlobalWidgetsLocalizations
.
load
(
locale
);
...
...
packages/flutter_localizations/test/basics_test.dart
View file @
796c5439
...
@@ -55,6 +55,9 @@ class _DummyLocalizationsDelegate extends LocalizationsDelegate<DummyLocalizatio
...
@@ -55,6 +55,9 @@ class _DummyLocalizationsDelegate extends LocalizationsDelegate<DummyLocalizatio
@override
@override
Future
<
DummyLocalizations
>
load
(
Locale
locale
)
async
=>
new
DummyLocalizations
();
Future
<
DummyLocalizations
>
load
(
Locale
locale
)
async
=>
new
DummyLocalizations
();
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
bool
shouldReload
(
_DummyLocalizationsDelegate
old
)
=>
true
;
bool
shouldReload
(
_DummyLocalizationsDelegate
old
)
=>
true
;
}
}
...
...
packages/flutter_localizations/test/override_test.dart
View file @
796c5439
...
@@ -8,18 +8,29 @@ import 'package:flutter_localizations/flutter_localizations.dart';
...
@@ -8,18 +8,29 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
class
FooMaterialLocalizations
extends
GlobalMaterialLocalizations
{
class
FooMaterialLocalizations
extends
GlobalMaterialLocalizations
{
FooMaterialLocalizations
(
Locale
locale
)
:
super
(
locale
);
FooMaterialLocalizations
(
Locale
locale
,
this
.
backButtonTooltip
)
:
super
(
locale
);
@override
@override
String
get
backButtonTooltip
=>
'foo'
;
final
String
backButtonTooltip
;
}
}
class
FooMaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
class
FooMaterialLocalizationsDelegate
extends
LocalizationsDelegate
<
MaterialLocalizations
>
{
const
FooMaterialLocalizationsDelegate
();
const
FooMaterialLocalizationsDelegate
({
this
.
supportedLanguage
:
'en'
,
this
.
backButtonTooltip
:
'foo'
});
final
String
supportedLanguage
;
final
String
backButtonTooltip
;
@override
bool
isSupported
(
Locale
locale
)
{
return
supportedLanguage
==
'allLanguages'
?
true
:
locale
.
languageCode
==
supportedLanguage
;
}
@override
@override
Future
<
FooMaterialLocalizations
>
load
(
Locale
locale
)
{
Future
<
FooMaterialLocalizations
>
load
(
Locale
locale
)
{
return
new
SynchronousFuture
<
FooMaterialLocalizations
>(
new
FooMaterialLocalizations
(
locale
));
return
new
SynchronousFuture
<
FooMaterialLocalizations
>(
new
FooMaterialLocalizations
(
locale
,
backButtonTooltip
));
}
}
@override
@override
...
@@ -143,7 +154,42 @@ void main() {
...
@@ -143,7 +154,42 @@ void main() {
expect
(
find
.
text
(
'Back'
),
findsOneWidget
);
expect
(
find
.
text
(
'Back'
),
findsOneWidget
);
});
});
testWidgets
(
'MaterialApp overrides MaterialLocalizations'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'MaterialApp adds MaterialLocalizations for additional languages'
,
(
WidgetTester
tester
)
async
{
final
Key
textKey
=
new
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
delegates:
<
FooMaterialLocalizationsDelegate
>[
const
FooMaterialLocalizationsDelegate
(
supportedLanguage:
'fr'
,
backButtonTooltip:
'FR'
),
const
FooMaterialLocalizationsDelegate
(
supportedLanguage:
'de'
,
backButtonTooltip:
'DE'
),
],
supportedLocales:
const
<
Locale
>[
const
Locale
(
'en'
,
''
),
const
Locale
(
'fr'
,
''
),
const
Locale
(
'de'
,
''
),
],
buildContent:
(
BuildContext
context
)
{
// Should always be 'foo', no matter what the locale is
return
new
Text
(
MaterialLocalizations
.
of
(
context
).
backButtonTooltip
,
key:
textKey
,
);
}
)
);
expect
(
tester
.
widget
<
Text
>(
find
.
byKey
(
textKey
)).
data
,
'Back'
);
await
tester
.
binding
.
setLocale
(
'fr'
,
'CA'
);
await
tester
.
pump
();
expect
(
find
.
text
(
'FR'
),
findsOneWidget
);
await
tester
.
binding
.
setLocale
(
'de'
,
'DE'
);
await
tester
.
pump
();
expect
(
find
.
text
(
'DE'
),
findsOneWidget
);
});
testWidgets
(
'MaterialApp overrides MaterialLocalizations for all locales'
,
(
WidgetTester
tester
)
async
{
final
Key
textKey
=
new
UniqueKey
();
final
Key
textKey
=
new
UniqueKey
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
...
@@ -151,7 +197,7 @@ void main() {
...
@@ -151,7 +197,7 @@ void main() {
// Accept whatever locale we're given
// Accept whatever locale we're given
localeResolutionCallback:
(
Locale
locale
,
Iterable
<
Locale
>
supportedLocales
)
=>
locale
,
localeResolutionCallback:
(
Locale
locale
,
Iterable
<
Locale
>
supportedLocales
)
=>
locale
,
delegates:
<
FooMaterialLocalizationsDelegate
>[
delegates:
<
FooMaterialLocalizationsDelegate
>[
const
FooMaterialLocalizationsDelegate
(),
const
FooMaterialLocalizationsDelegate
(
supportedLanguage:
'allLanguages'
),
],
],
buildContent:
(
BuildContext
context
)
{
buildContent:
(
BuildContext
context
)
{
// Should always be 'foo', no matter what the locale is
// Should always be 'foo', no matter what the locale is
...
@@ -174,6 +220,38 @@ void main() {
...
@@ -174,6 +220,38 @@ void main() {
expect
(
find
.
text
(
'foo'
),
findsOneWidget
);
expect
(
find
.
text
(
'foo'
),
findsOneWidget
);
});
});
testWidgets
(
'MaterialApp overrides MaterialLocalizations for default locale'
,
(
WidgetTester
tester
)
async
{
final
Key
textKey
=
new
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
delegates:
<
FooMaterialLocalizationsDelegate
>[
const
FooMaterialLocalizationsDelegate
(
supportedLanguage:
'en'
),
],
// supportedLocales not specified, so all locales resolve to 'en'
buildContent:
(
BuildContext
context
)
{
return
new
Text
(
MaterialLocalizations
.
of
(
context
).
backButtonTooltip
,
key:
textKey
,
);
}
)
);
// Unsupported locale '_' (the widget tester's default) resolves to 'en'.
expect
(
tester
.
widget
<
Text
>(
find
.
byKey
(
textKey
)).
data
,
'foo'
);
// Unsupported locale 'zh' resolves to 'en'.
await
tester
.
binding
.
setLocale
(
'zh'
,
'CN'
);
await
tester
.
pump
();
expect
(
find
.
text
(
'foo'
),
findsOneWidget
);
// Unsupported locale 'de' resolves to 'en'.
await
tester
.
binding
.
setLocale
(
'de'
,
'DE'
);
await
tester
.
pump
();
expect
(
find
.
text
(
'foo'
),
findsOneWidget
);
});
testWidgets
(
'deprecated Android/Java locales are modernized'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'deprecated Android/Java locales are modernized'
,
(
WidgetTester
tester
)
async
{
final
Key
textKey
=
new
UniqueKey
();
final
Key
textKey
=
new
UniqueKey
();
...
...
packages/flutter_localizations/test/widgets_test.dart
View file @
796c5439
...
@@ -35,6 +35,9 @@ class SyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizati
...
@@ -35,6 +35,9 @@ class SyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizati
final
String
prefix
;
// Changing this value triggers a rebuild
final
String
prefix
;
// Changing this value triggers a rebuild
final
List
<
bool
>
shouldReloadValues
=
<
bool
>[];
final
List
<
bool
>
shouldReloadValues
=
<
bool
>[];
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
TestLocalizations
>
load
(
Locale
locale
)
=>
TestLocalizations
.
loadSync
(
locale
,
prefix
);
Future
<
TestLocalizations
>
load
(
Locale
locale
)
=>
TestLocalizations
.
loadSync
(
locale
,
prefix
);
...
@@ -54,6 +57,9 @@ class AsyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizat
...
@@ -54,6 +57,9 @@ class AsyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizat
final
String
prefix
;
// Changing this value triggers a rebuild
final
String
prefix
;
// Changing this value triggers a rebuild
final
List
<
bool
>
shouldReloadValues
=
<
bool
>[];
final
List
<
bool
>
shouldReloadValues
=
<
bool
>[];
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
TestLocalizations
>
load
(
Locale
locale
)
=>
TestLocalizations
.
loadAsync
(
locale
,
prefix
);
Future
<
TestLocalizations
>
load
(
Locale
locale
)
=>
TestLocalizations
.
loadAsync
(
locale
,
prefix
);
...
@@ -92,6 +98,9 @@ class SyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizati
...
@@ -92,6 +98,9 @@ class SyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizati
@override
@override
Future
<
MoreLocalizations
>
load
(
Locale
locale
)
=>
MoreLocalizations
.
loadSync
(
locale
);
Future
<
MoreLocalizations
>
load
(
Locale
locale
)
=>
MoreLocalizations
.
loadSync
(
locale
);
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
bool
shouldReload
(
SyncMoreLocalizationsDelegate
old
)
=>
false
;
bool
shouldReload
(
SyncMoreLocalizationsDelegate
old
)
=>
false
;
}
}
...
@@ -100,6 +109,9 @@ class AsyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizat
...
@@ -100,6 +109,9 @@ class AsyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizat
@override
@override
Future
<
MoreLocalizations
>
load
(
Locale
locale
)
=>
MoreLocalizations
.
loadAsync
(
locale
);
Future
<
MoreLocalizations
>
load
(
Locale
locale
)
=>
MoreLocalizations
.
loadAsync
(
locale
);
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
bool
shouldReload
(
AsyncMoreLocalizationsDelegate
old
)
=>
false
;
bool
shouldReload
(
AsyncMoreLocalizationsDelegate
old
)
=>
false
;
}
}
...
@@ -112,6 +124,9 @@ class OnlyRTLDefaultWidgetsLocalizations extends DefaultWidgetsLocalizations {
...
@@ -112,6 +124,9 @@ class OnlyRTLDefaultWidgetsLocalizations extends DefaultWidgetsLocalizations {
class
OnlyRTLDefaultWidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
class
OnlyRTLDefaultWidgetsLocalizationsDelegate
extends
LocalizationsDelegate
<
WidgetsLocalizations
>
{
const
OnlyRTLDefaultWidgetsLocalizationsDelegate
();
const
OnlyRTLDefaultWidgetsLocalizationsDelegate
();
@override
bool
isSupported
(
Locale
locale
)
=>
true
;
@override
@override
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
{
Future
<
WidgetsLocalizations
>
load
(
Locale
locale
)
{
return
new
SynchronousFuture
<
WidgetsLocalizations
>(
new
OnlyRTLDefaultWidgetsLocalizations
());
return
new
SynchronousFuture
<
WidgetsLocalizations
>(
new
OnlyRTLDefaultWidgetsLocalizations
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment