flutter app does not load local device language - flutter

I implemented the Easy localization package on my app, and it works fine when i use the app radio button switch between the different languages. But the aim it is not to let users change language, it is to load local device language and set the app with the local language.
I have changed device language in device settings, but when i re-open the app, language does not change.
Here the main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en', 'US'),
Locale('it', 'IT'),
Locale('fr', 'FR')
],
path: 'assets/translations',
// <-- change the path of the translation files
fallbackLocale: Locale('en', 'US'),
//assetLoader: CodegenLoader(),
child: MyLangApp(),
),
);
}
Here the MyLangApp:
class MyLangApp extends StatefulWidget {
const MyLangApp({Key? key}) : super(key: key);
#override
State<MyLangApp> createState() => _MyLangAppState();
}
class _MyLangAppState extends State<MyLangApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: MainPage(),
);
}
}

If you want to get the devices locale use this:
import 'dart:io';
final String defaultLocale = Platform.localeName;
see easy_localization documentation (https://pub.dev/packages/easy_localization) for changing the language:
Found this in the Flutter documentation(https://docs.flutter.dev/development/accessibility-and-localization/internationalization):
Advanced locale definition
Some languages with multiple variants require more than just a language code to properly differentiate.
For example, fully differentiating all variants of Chinese requires specifying the language code, script code, and country code. This is due to the existence of simplified and traditional script, as well as regional differences in the way characters are written within the same script type.
In order to fully express every variant of Chinese for the country codes CN, TW, and HK, the list of supported locales should include:
supportedLocales: [
Locale.fromSubtags(languageCode: 'zh'), // generic Chinese 'zh'
Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hans'), // generic simplified Chinese 'zh_Hans'
Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant'), // generic traditional Chinese 'zh_Hant'
Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hans',
countryCode: 'CN'), // 'zh_Hans_CN'
Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
countryCode: 'TW'), // 'zh_Hant_TW'
Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
countryCode: 'HK'), // 'zh_Hant_HK'
],
This explicit full definition ensures that your app can distinguish between and provide the fully nuanced localized content to all combinations of these country codes. If a user’s preferred locale is not specified, then the closest match is used instead, which likely contains differences to what the user expects. Flutter only resolves to locales defined in supportedLocales. Flutter provides scriptCode-differentiated localized content for commonly used languages. See Localizations for information on how the supported locales and the preferred locales are resolved.
Although Chinese is a primary example, other languages like French (fr_FR, fr_CA) should also be fully differentiated for more nuanced localization.
Seems that you have to include them all or split the Platform.localeName into language and region and only use language then...
Update
try this:
final deviceLocale= Locale(Platform.localeName)
await context.setLocale(deviceLocale.split('-')[0]);

Related

How to you change the locale of a flutter app while running?

I'm using
import 'package:flutter_localizations/flutter_localizations.dart'; //For Cupertino stuff
import 'package:localization/localization.dart'; //For actual translations
import 'package:intl/intl.dart'; //For locales
to localize my flutter app. It comes up in the language the phone is set to, but I'd like to add a way to change the language within th e app...I tried using LocalJsonLocalization.delegate.load(locale(lang)) from a button (for now; I'd like to use a dropdown list box but that doesn't seem to be null safe yet), but that didn't actually make the change (I saw the debug log and it said it couldn't load the json language file)...
Try wrapping your MaterialApp in a BlocBuilder.
return BlocBuilder<MainBloc, MainState>(
builder: (context, mainState) {
return MaterialApp(
title: 'MyApp',
locale: mainState.locale,
supportedLocales: L10n.all,
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
);
Then from your button just call the Bloc Event that will change the state of the locale.
Do not forget to add:
WidgetsFlutterBinding.ensureInitialized();
at the beginning of main() function
It should also work fine using Provider.

how to set english as default language when changing language in settings?

How can I set the default language to English if I changed the language in the settings
in this case, I do not have the first language localized, but the other two are localized
therefore, I will always have a second language by default, but I want only English in any such situations
that is, if my language is not localized, I want it to be English instead
i used https://pub.dev/packages/intl library
There is a locale property inside the material app , your can set it to your default language
locale: _locale,
Locale _locale = const Locale('en', '');
return const MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: List.from(AppLocalizations.supportedLocales)..sort((a, b) => b.languageCode == "en" ? 1 : 0),
home: MyHomePage(),
);

How can I use a localized string from GlobalMaterialLocalizations?

I want to use one of the predefined localized strings available in the GlobalMaterialLocalizations class. I have added the necessary bits and pieces to my MaterialApp
MaterialApp(
localizationsDelegates: [
const LocalizationDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''),
const Locale('sv', ''),
],
localeResolutionCallback:(Locale locale, Iterable<Locale> supportedLocales) {
return locale; // Return a different locale if the user choose another language in the settings
},
...
and my custom LocalizationDelegate is working fine. I just can't figure out how to use the predefined strings in GlobalMaterialLocalizations, since there is no GlobalMaterialLocalizations.of(BuildContext) method?
Turns out I was looking for the .of(BuildContext) method in the wrong class. To actually use the strings, the MaterialLocalizations class should be used.
Text( MaterialLocalizations.of(context).okButtonLabel )
Hope it might help someone else struggling with the same problem.

Flutter CupertinoDatePicker - can I swap month and day positions?

I need to use CupertinoDatePicker, however its date formatting is mm-dd-yyyy, which in fact is not common for a specific location, where my app will be distributed. I would like to change the format to dd-mm-yyyy, which IMO seems more general.
Is that possible, using that picker?
EDIT: It should be possible in Flutter version 1.7
According to the CupertinoDatePicker documentation:
the class will display its children as
consecutive columns. Its children order is based on
internationalization.
You can read more about internationalization Flutter apps here.
You need to add this to your pubspec.yaml file:
dependencies:
flutter_localizations:
sdk: flutter
And then in your root widget add proper localizationsDelegates:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Application',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''),
const Locale('fr', ''),
],
home: Scaffold(
body: Container(),
),
);
}
}
If you'll use in app one of the localizations that supports dd-mm-yyyy format, e.g. UK English, and you'll have this language set on your device, you should see this widget changed accordingly.

Supporting multiple languages for constant strings in Flutter

I would like to start putting all my constant strings (like labels etc.) into a place that can be translated at a later stage.
How is this handled in Flutter?
Create a Localizations.dart file
Add the following code to that file:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show SynchronousFuture;
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'title': 'App title',
'googleLogin': 'Login with Google'
},
'es': {
'title': 'Título de App',
'googleLogin': 'Conectar con Google'
},
};
String get title {
return _localizedValues[locale.languageCode]['title'];
}
String get googleLogin {
return _localizedValues[locale.languageCode]['googleLogin'];
}
}
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
#override
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
#override
Future<DemoLocalizations> load(Locale locale) {
// Returning a SynchronousFuture here because an async "load" operation
// isn't needed to produce an instance of DemoLocalizations.
return new SynchronousFuture<DemoLocalizations>(new DemoLocalizations(locale));
}
#override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
Import Localizations.dart into the file where you use the strings.
Add the delegate DemoLocalizationsDelegate in the MaterialApp
MaterialApp(
localizationsDelegates: [
MyLocalizationsDelegate(),
],
...
)
Substitute new Text("App Title"), with new Text(DemoLocalizations.of(context).title),
For each new string you want to localize, you need to add the translated text to each language's map and then add the String get... line.
It's a bit cumbersome but it does what you need it to.
This is a quick overview of one way of doing it.
You can read more about it in the Flutter docs: https://flutter.io/tutorials/internationalization/
I asked on gitter and I got the following:
Translation/Internationalization isn't a feature we consider "done"
yet. https://pub.dartlang.org/packages/intl works in Flutter. We have
a bug tracking this more generally: flutter/flutter#393
More complete internationalization (i18n) and accessibility support
are two of the big arcs of work ahead of Flutter in the coming months.
Another example of i18n work we have planned, is completing
Right-to-left (RTL) layouts for our provided Widgets (e.g. teaching
the Material library's Scaffold to place the Drawer on the left when
the locale is an RTL language). RTL Text support works today, but
there are no widgets which are out-of-the-box RTL-layout aware at this
moment.