Reputation: 2117
I have in my settings page the ability for the user to change the app theme at runtime, but I am running into some problems.
The problem that I am using shared preferences with Riverpod to store the changes made in my settings page and whenever I change the theme, my dialog selector and settings screen closes, and it takes me back to the home screen.
I don't want that to happen. I want the user to stay on the settings page and see the changes on the settings page itself, rather than resetting to the default route.
I've built apps using native android and Kotlin, and this was the normal behavior there.
Can you help me achieve the same thing here?
Below is my code:
class MesMaterialApp extends ConsumerWidget {
MesMaterialApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// Retrieve the router
final router = MesAppRouter.getRouter(
initialLocation: ref.watch(settingsProvider.select((s) => s.isOnboarded))
? HomeRoute.path
: WelcomeRoute.path,
);
// Determine the app brightness (theme)
final brightness = View.of(context).platformDispatcher.platformBrightness;
// Create the text theme
TextTheme textTheme = createTextTheme(context, "Poppins", "Lato");
// Create the app bar theme
AppBarTheme appBarTheme = createAppBarTheme(
brightness == Brightness.light,
);
// Create the material theme
MaterialTheme theme = MaterialTheme(
textTheme,
appBarTheme,
);
// Return the Material App
return MaterialApp.router(
debugShowCheckedModeBanner: false,
// debugShowMaterialGrid: true,
title: 'Flutter Demo',
theme: theme.light(),
darkTheme: theme.dark(),
themeMode: ref.watch(settingsProvider.select(
(s) => s.theme,
)),
highContrastTheme: theme.lightHighContrast(),
highContrastDarkTheme: theme.darkHighContrast(),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
routerConfig: router,
);
}
}
Below is my router code:
class MesAppRouter {
static GoRouter getRouter({String initialLocation = HomeRoute.path}) {
return GoRouter(
initialLocation: initialLocation,
routes: <RouteBase>[
GoRoute(
name: WelcomeRoute.name,
path: WelcomeRoute.path,
builder: (BuildContext context, GoRouterState state) {
return const WelcomeScreen();
},
),
GoRoute(
name: HomeRoute.name,
path: HomeRoute.path,
pageBuilder: (BuildContext context, GoRouterState state) {
return CustomTransitionPage(
key: state.pageKey,
child: HomeScreen(),
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
return ScaleTransition(
scale: Tween<double>(
begin: 0.95,
end: 1.0,
).animate(animation),
child: child,
);
},
);
},
),
GoRoute(
name: ServicesRoute.name,
path: ServicesRoute.path,
pageBuilder: (BuildContext context, GoRouterState state) {
final String query;
if (state.extra != null) {
final data = state.extra as Map<String, dynamic>;
query = data[ServicesRoute.extraQuery];
// Use data safely here
} else {
query = "";
// Handle case where extra is null
}
return CustomTransitionPage(
key: state.pageKey,
child: ServicesScreen(
searchQuery: query,
),
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
return ScaleTransition(
scale: Tween<double>(
begin: 0.95,
end: 1.0,
).animate(animation),
child: child,
);
},
);
},
),
GoRoute(
name: CycloneReportRoute.name,
path: CycloneReportRoute.path,
pageBuilder: (BuildContext context, GoRouterState state) {
return CustomTransitionPage(
key: state.pageKey,
child: CycloneScreen(),
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
return ScaleTransition(
scale: Tween<double>(
begin: 0.95,
end: 1.0,
).animate(animation),
child: child,
);
},
);
},
),
GoRoute(
name: PrecallRoute.name,
path: PrecallRoute.path,
builder: (BuildContext context, GoRouterState state) {
final data = state.extra! as Map<String, dynamic>;
return PreCallScreen(
service: data[PrecallRoute.extraService],
number: data[PrecallRoute.extraNumber].toString(),
onComplete: () => context.goBack(),
);
},
),
GoRoute(
name: AboutRoute.name,
path: AboutRoute.path,
builder: (BuildContext context, GoRouterState state) {
return const AboutScreen();
},
),
GoRoute(
name: SettingsRoute.name,
path: SettingsRoute.path,
builder: (BuildContext context, GoRouterState state) {
return const SettingsScreen();
},
),
],
);
}
}
Upvotes: 1
Views: 62
Reputation: 4824
Apparently, the problem is in this line of code:
@override
Widget build(BuildContext context, WidgetRef ref) {
// Retrieve the router
final router = MesAppRouter.getRouter(
initialLocation: ref.watch(settingsProvider.select((s) => s.isOnboarded))
? HomeRoute.path
: WelcomeRoute.path,
);
Of course, you need to look at what your MesAppRouter.getRouter
looks like, but apparently it creates a router
in which the current active route becomes "home screen".
I assume that the solution would be to turn MesAppRouter
into a Notifier
class, in which you could make the necessary settingsProvider.select((s) => s.isOnboarded)
redirects, but your current route would not be reset by changes in the application theme (and other conditions)
Upvotes: 1