I’m encountering an issue with Cubit in Flutter. In my main.dart
, I have initialized three providers: one for language, one for theme, and one for connectivity. Everything seems to be set up correctly, and I’m able to change the theme without any problems. However, when I try to change the language by executing context.read<LanguageCubit>().changeLanguage(LANGUAGE.tr.name);
from the home screen, the language value changes internally but the UI does not update to reflect this change. This issue seems to be specific to the language Cubit; the theme changes are reflected on the UI as expected. What could be causing the language changes not to trigger a UI update?
Main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp],
);
final appRouter = AppRouter();
runApp(
EasyLocalization(
supportedLocales: [
Locale(LANGUAGE.en.name, ''),
Locale(LANGUAGE.tr.name, ''),
],
path: ApplicationConstants.LANG_ASSET_PATH,
startLocale: Locale(LANGUAGE.tr.name, ''),
child: MyApp(appRouter: appRouter),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({required this.appRouter, super.key});
final AppRouter appRouter;
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => ThemeCubit()..getSavedTheme()),
BlocProvider(create: (context) => LanguageCubit()..getSavedLanguage()),
BlocProvider(create: (context) => ConnectivityCubit()),
],
child: Builder(
builder: (context) {
final languageCubit = context.watch<LanguageCubit>();
final themeCubit = context.watch<ThemeCubit>();
// final connectivityCubit = context.watch<ConnectivityCubit>();
return MaterialApp.router(
routeInformationParser: appRouter.defaultRouteParser(),
routerDelegate: appRouter.delegate(),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: languageCubit.state.locale,
theme: themeCubit.state.themeData,
debugShowCheckedModeBanner: false,
builder: CustomResponsive.build,
);
},
),
);
}
}
languageCubit.dart
part 'language_state.dart';
class LanguageCubit extends Cubit<ChangeLanguageState> {
LanguageCubit()
: super(ChangeLanguageState(
locale: Locale(ApplicationConstants.DEFAULT_LANGUAGE.name, '')));
Future<void> getSavedLanguage() async {
final cachedLanguageCode = await LanguageCacheHelper().getCachedLanguage();
emit(ChangeLanguageState(locale: Locale(cachedLanguageCode, '')));
}
Future<void> changeLanguage(String languageCode) async {
emit(ChangeLanguageState(locale: Locale(languageCode, '')));
}
}
language_state.dart
part of 'language_cubit.dart';
class ChangeLanguageState {
ChangeLanguageState({
required this.locale,
});
final Locale locale;
}
home.dart
@RoutePage()
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(LocaleKeys.home_title.tr()),
),
body: Column(
children: [
ElevatedButton(
onPressed: () {
context.read<LanguageCubit>().changeLanguage(LANGUAGE.tr.name);
print(context.read<LanguageCubit>().state.locale.toString());
// context.setLocale(Locale('tr'));
},
child: Text(LocaleKeys.tr_lang.tr()),
),
ElevatedButton(
onPressed: () {
context.read<LanguageCubit>().changeLanguage(LANGUAGE.en.name);
print(context.read<LanguageCubit>().state.locale.toString());
// context.setLocale(Locale('en'));
},
child: Text(LocaleKeys.en_lang.tr()),
),
],
),
);
}
}
2
Answers
Your state needs to extend
Equatable
and then you have tooverride
props and pass there your state variables. Then, you should implement thecopyWith
pattern for yourChangeLanguageState
to update the existentChangeLanguageState
.use the language code for your state.
for ex:
Then use it like that: