Closed red-star25 closed 1 year ago
I have the same regression on my app too. The local has been changed, but there is now refresh. Is this a breaking change and how can I force a refresh on locale change if so ?
For me the app text direction changes based on the new language(rtl) but the new languages' keys doesn't load and UI not updating. No error messages
Same thing happening on my app
same issue here
same energy on my end
Thanks for issue, i will check
I have the same problem with easy_localization: ^3.0.0
with Arabic and English, when changing the current locale the direction changes but the actual localized titles don't.
the same issue in my app. any updates?
I found where is the isuue is. I use GetMaterialApp
from Get
package to initialize App.
GetMaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, debugShowCheckedModeBanner: false, initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, ),
When I change it to normal one it works.
MaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, debugShowCheckedModeBanner: false, initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, ),
I found where is the isuue is. I use
GetMaterialApp
fromGet
package to initialize App.GetMaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, debugShowCheckedModeBanner: false, initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, ),
When I change it to normal one it works.
MaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, debugShowCheckedModeBanner: false, initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, ),
This issue here that simply removing GetMaterialApp
will be very difficult because literally, the whole app depends on it.
I have found a possible solution.
In case you are using GetMaterialApp
you should when changing the current language call Get.updateLocale()
to inform GetMaterialApp
about the language change
final _newLocale = Locale('ar', 'EG')
await context.setLocale(_newLocale); // change `easy_localization` locale
Get.updateLocale(_newLocale); // change `Get` locale direction
I have found a possible solution.
In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
It worked thanks π
I have found a possible solution.
In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
Okay @AhmedAbouelkher Thanks for the Solution. It's working now π I'm closing the issue now..
I have found a possible solution.
In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
What if you aren't using Get? I still have this problem!
Same issue here with 2.3.3 (can't use 3.0 due to not supporting flutter 2.0 in the current app) and not using Get. Need to actually hot reload the app for changes to actually take place, if not the font size weirdly changes but not the language.
Just posting again to say that this actually works: https://stackoverflow.com/questions/43778488/how-to-force-flutter-to-rebuild-redraw-all-widgets
@override
Widget build(BuildContext context) {
rebuildAllChildren(context);
return MaterialApp( ....
}
void rebuildAllChildren(BuildContext context) {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(context as Element).visitChildren(rebuild);
}
It was posted by the author of the i18n_extension ( https://pub.dev/packages/i18n_extension ) and even though it shouldn't be recommended it seems to be the only way to inmediately refresh the widget tree to show the new locale properly.
I had the same problem, becuase I was missing locale: context.locale,
in MaterialApp
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: MyHomePage()
);
}
}
our app is not using Get, it has locale: context.locale
set and still the language changes only if the whole screen is redrawn (ie. closed and opened again) - any other widget that's visible or was created before the language change doesn't change its content to match selected language.
using a DropdownButton to set locale
onChanged: (value) async {
if (value != null) {
await context.setLocale(value);
}
},
example of 2 locale changes, one after the other
I/flutter (19778): [π Easy Localization] [DEBUG] Load asset from assets/translations
I/flutter (19778): [π Easy Localization] [INFO] Locale de changed
I/flutter (19778): [π Easy Localization] [DEBUG] Build
I/flutter (19778): [π Easy Localization] [DEBUG] Init Localization Delegate
I/flutter (19778): [π Easy Localization] [DEBUG] Init provider
I/flutter (19778): [π Easy Localization] [DEBUG] Load Localization Delegate
I/flutter (19778): [π Easy Localization] [INFO] Locale de saved
I/flutter (19778): [π Easy Localization] [DEBUG] Load asset from assets/translations
I/flutter (19778): [π Easy Localization] [INFO] Locale en changed
I/flutter (19778): [π Easy Localization] [DEBUG] Build
I/flutter (19778): [π Easy Localization] [DEBUG] Init Localization Delegate
I/flutter (19778): [π Easy Localization] [DEBUG] Init provider
I/flutter (19778): [π Easy Localization] [DEBUG] Load Localization Delegate
I/flutter (19778): [π Easy Localization] [INFO] Locale en saved
our app is not using Get, it has
locale: context.locale
set and still the language changes only if the whole screen is redrawn (ie. closed and opened again) - any other widget that's visible or was created before the language change doesn't change its content to match selected language.using a DropdownButton to set locale
onChanged: (value) async { if (value != null) { await context.setLocale(value); } },
example of 2 locale changes, one after the other
I/flutter (19778): [π Easy Localization] [DEBUG] Load asset from assets/translations I/flutter (19778): [π Easy Localization] [INFO] Locale de changed I/flutter (19778): [π Easy Localization] [DEBUG] Build I/flutter (19778): [π Easy Localization] [DEBUG] Init Localization Delegate I/flutter (19778): [π Easy Localization] [DEBUG] Init provider I/flutter (19778): [π Easy Localization] [DEBUG] Load Localization Delegate I/flutter (19778): [π Easy Localization] [INFO] Locale de saved I/flutter (19778): [π Easy Localization] [DEBUG] Load asset from assets/translations I/flutter (19778): [π Easy Localization] [INFO] Locale en changed I/flutter (19778): [π Easy Localization] [DEBUG] Build I/flutter (19778): [π Easy Localization] [DEBUG] Init Localization Delegate I/flutter (19778): [π Easy Localization] [DEBUG] Init provider I/flutter (19778): [π Easy Localization] [DEBUG] Load Localization Delegate I/flutter (19778): [π Easy Localization] [INFO] Locale en saved
Could you share you MaterialApp
widget?
I tried this solution which allows me to rebuild the whole widget tree by adding a new unique key every time the localization change.
return MaterialApp(
key: UniqueKey(),
our app is not using Get, it has
locale: context.locale
set and still the language changes only if the whole screen is redrawn (ie. closed and opened again) - any other widget that's visible or was created before the language change doesn't change....Could you share you
MaterialApp
widget?
Here you go:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [Locale('en'), Locale('de')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
child: App(),
),
);
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: MainScreen(),
);
}
}
I tried this solution which allows me to rebuild the whole widget tree by adding a new unique key every time the localization change.
return MaterialApp( key: UniqueKey(),
this really feels like too much to do to in Flutter whose performance is based on redrawing only necessary views...
I have found a possible solution. In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
Okay @AhmedAbouelkher Thanks for the Solution. It's working now π I'm closing the issue now..
I have used it. But still sometime not working.
`if (newValue == LocaleKeys.arabic.tr()) { this.setState(() { dropdownValue = LocaleKeys.arabic.tr();
context.setLocale(Locale('ar'));
});`
`if (newValue == LocaleKeys.arabic.tr()) { this.setState(() { dropdownValue = LocaleKeys.arabic.tr();
context.setLocale(Locale('ar')); });`
no, that does nothing...
`if (newValue == LocaleKeys.arabic.tr()) {
this.setState(() {
dropdownValue = LocaleKeys.arabic.tr();
context.setLocale(Locale('ar')); });`
no, that does nothing...
it's work with me
yeah, thank you, your comment made me think and it seems that in my case it doesn't work (doesn't rebuild the screen on which the dropdown is) because the dropdown button and setLocale
are located several widgets away from the content that should change language but didn't.
I will now implement some kind of listener or move the whole setLocale
logic up the tree and use setState
to force a refresh.
Why is this closed?
same issue here, Why is this closed ?
Same issue, only some widgets are rebuilding, but most of the app stays in the old selected language.
Having the same issue.
Having the same issue.
I managed to solve it by rebuilding my MaterialApp
whenever the language change. The following is my bloc implementation:
BlocBuilder<LocalizaitionCubit,LocalizaitionState>(
buildWhen: (state, newState) =>
newState is LocalizationLanguageUpdatedState && newState.current.languageCode != context.locale.languageCode,
builder: (context, state) {
return MaterialApp.router(
key: ValueKey('${context.locale}'),
.......)
@nullbytesoftware I read somewhere that it is not recommended. Does it rebuild everything or restarts the app completely?
@nullbytesoftware I read somewhere that it is not recommended. Does it rebuild everything or restarts the app completely?
Yes it does rebuild the whole app. I have my providers & dependences above βMaterialAppβ so it doesnβt matter for my use case.
@nullbytesoftware cool I'll try it out. But I think this package should do it internally tho.
As a band aid solution, the following seems to work:
Widget build(BuildContext context) {
context.locale; // add this line
I don't know if this might help for people that are not using Get. The issue is the way flutter tries to rebuild widgets. Taking a look at the flutter hot reload article might explain better. Apparently, if you have variables you declared final, they might not get rebuilt. The trick is to use 'get' in replacement of final.
E.g
final bar = foo;
to
int get bar => foo;
And also add this to your main.dart
void rebuildAllChildren(BuildContext context) {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(context as Element).visitChildren(rebuild);
}
and call rebuildAllChildren immediately after build context of your MaterialApp
This works for me. I hope it does for you.
I am also having this issue. The UI is not rebuilding the updated translations. I am using Riverpod for state management with Navigator 2.0 (using the Routemaster package). Here is my MaterialApp.router()
.
I am using
context.setLocale(newLocale);
Flutter 2.5.1 with sound null safety.
void main() async {
// This is just needed for many things to work.
WidgetsFlutterBinding.ensureInitialized();
// Init Easy Localization
await EasyLocalization.ensureInitialized();
// Run the main app
runApp(
EasyLocalization(
supportedLocales: const [
Locale('de', 'DE'),
Locale('en', 'US'),
Locale('es', 'ES'),
Locale('fr', 'FR'),
Locale('it', 'IT'),
Locale('ja', 'JP'),
Locale('ko', 'KR'),
Locale('pt', 'BR'),
],
path: 'assets/translations',
saveLocale: true,
fallbackLocale: const Locale('en', 'US'),
child: const ProviderScope(
child: MyApp(),
),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
/// InitState
@override
void initState() {
super.initState();
var widgetsBinding = WidgetsBinding.instance;
if (widgetsBinding != null) {
widgetsBinding.addPostFrameCallback((_) async {
// Initialize app features
initAppFeatures(context);
});
}
}
@override
Widget build(BuildContext context) {
return Consumer(builder: (context, watch, child) {
return FeatureDiscovery(
child: MaterialApp.router(
locale: context.locale,
supportedLocales: context.supportedLocales,
localizationsDelegates: context.localizationDelegates,
debugShowCheckedModeBanner: false,
scaffoldMessengerKey: rootScaffoldMessengerKey,
title: 'MyApp',
theme: ConnectTheme.themeData(context),
routerDelegate: RoutemasterDelegate(
routesBuilder: (context) {
// Watch for user state changes to rebuild our RouteMap based on user login state
RouteMap _routeMap = watch(routeMapProvider);
return _routeMap;
},
),
routeInformationParser: RoutemasterParser(),
),
);
});
}
}
Logs after changing locale
flutter: \^[[90m[π Easy Localization] [DEBUG] Load asset from assets/translations<β¦>
flutter: \^[[32m[π Easy Localization] [INFO] Locale ja_JP changed<β¦>
flutter: \^[[90m[π Easy Localization] [DEBUG] Build<β¦>
flutter: \^[[90m[π Easy Localization] [DEBUG] Init Localization Delegate<β¦>
flutter: \^[[90m[π Easy Localization] [DEBUG] Init provider<β¦>
flutter: \^[[90m[π Easy Localization] [DEBUG] Load Localization Delegate<β¦>
flutter: \^[[32m[π Easy Localization] [INFO] Locale ja_JP saved<β¦>
I can confirm that @nullbytesoftware solution of adding the key
param connected to context.locale
did fix this for me. However, as others have mentioned, this seems like a poor solution because only the individual translated widgets should be rebuilding. Specifically, this is rebuilding my routes (Navigator 2.0) so the users loses their position within the app when the language changes.
MaterialApp.router(
key: ValueKey('${context.locale}'),
Other dependencies in case relevant:
dependencies:
firebase_core: ^1.6.0
firebase_analytics: ^8.3.2
horizontal_data_table: 3.4.2
routemaster: ^0.10.0-dev2
collection: ^1.15.0
artemis: ^7.1.1-beta.1
logger: ^1.0.0
flutter_riverpod: ^0.14.0+3
graphql: ^5.0.0
json_annotation: ^4.1.0
freezed_annotation: ^0.14.3
email_validator: ^2.0.1
meta: ^1.7.0
equatable: ^2.0.3
url_launcher: ^6.0.11
flutter_markdown: ^0.6.6
charts_flutter:
git:
url: git://github.com/google/charts.git
path: charts_flutter
feature_discovery: ^0.14.0
flutter_appauth: ^1.1.0
flutter_appauth_web:
path: ./custom_packages/flutter_appauth_web
flutter:
sdk: flutter
shared_preferences: ^2.0.7
easy_localization: ^3.0.0
@Overman775 - Any new ideas? I had no issues with 2.3.3+1, but now that I am migrating to null safety, I need 3.0.
I'd like to note, that the solution I implemented above (https://github.com/aissat/easy_localization/issues/370#issuecomment-927223962) is not working well. The "refresh" sometimes does not change the language.
If I change it again to a third language, it may switch to the second language I tried. After a few changes, it starts working better. It's very odd. I think it could be a file loading issue for larger translation files? Not sure yet.
Edit / Update: I refactored my app to utilize the Flutter native localization features with Riverpod state management for real-time persistent language changes, which has been much more reliable.
I have an example repo here (where Riverpod manages the language state). This has totally replaced any needs or advantages that easy_localization once provided. https://github.com/mdrideout/Riverpod-Localization
I think the package should add listen
property in tr() or plural() method to listen locale change every time. Under the hood, it just call the context.locale function to call context.dependOnInheritedWidgetOfExactType
.
I have found a possible solution. In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
It worked thanks π
I have found a possible solution.
In case you are using
GetMaterialApp
you should when changing the current language callGet.updateLocale()
to informGetMaterialApp
about the language changefinal _newLocale = Locale('ar', 'EG') await context.setLocale(_newLocale); // change `easy_localization` locale Get.updateLocale(_newLocale); // change `Get` locale direction
Work great!!!
I Just Add this cheat on my screen
Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; print(context.locale);
and itworks
easy_localization : ^3.0.0
I also went on that "print in the build method" path but that didn't solve the problem when running the app in profile mode and also, it's really a cheat, feels awkward and weird to see that something should work that way. I do see it as a part of the search for a solution, as it seems to me that the print() command delays the return from the build method for just enough time for setLocale to really set the locale... It feels like setLocale takes its time to change the locale and does so after the build method has returned. if that makes sense..
Any workaround? none of the above solutions worked for me.
I think the package should add
listen
property in tr() or plural() method to listen locale change every time. Under the hood, it just call the context.locale function to callcontext.dependOnInheritedWidgetOfExactType
.
I agree. It doesn't make sense that changing the locale only updates the internal value but doesn't trigger a state update. The only solutions I've seen so far are:
context.locale
and its associated methods, since the value will be tracked in your own custom state anyways. At that point you may as well implement your own localization system like #370 (@mdrideout) suggests.Ideally, the context.locale
and tr()
values should be reactive and rebuild the widgets that depend on them.
I ended up doing without this package. In fact, flutter has very good documentation. I followed the documentation and solve the issue. Here is official documentation about internationalization and localization in Flutter.
any update on this issue? or maybe how to use this package properly
I Just Add this cheat on my screen
Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; print(context.locale);
and itworks
easy_localization : ^3.0.0
this works to me thx xD
same problem
I've updated easy_localization: 3.0.0 package from easy_localization: ^2.3.3. When i was using easy_localization: ^2.3.3 it is updating my app locale instantly whenever i called
But since I've updated the package version to 3.0.0 it is not updating the locale instantly. I've to hot restart the whole app to see the changes.
Here is what im doing in version 3.0.0
onTap: () async { await homeController .setLanguage("EN") .then((value) async { await context .setLocale( const Locale( "en")); }) },
And here is what im doing in version 2.3.3 (which is working,and updating locale instantly)
onTap: () { homeController .setLanguage("EN"); setState(() { context.locale = const Locale( "en"); }); },