admin管理员组文章数量:1323730
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();
},
),
],
);
}
}
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();
},
),
],
);
}
}
Share
Improve this question
edited Jan 12 at 15:34
Mervin Hemaraju
asked Jan 12 at 6:04
Mervin HemarajuMervin Hemaraju
2,1873 gold badges37 silver badges87 bronze badges
2
- Is MesAppRouter instance getting rebuilt perhaps? That would lose your place in the app. – Randal Schwartz Commented Jan 12 at 7:16
- I think it's my settings provider because if i comment it out, it doesn't get rebuilt. But then how will i update the settings? – Mervin Hemaraju Commented Jan 12 at 7:38
1 Answer
Reset to default 1Apparently, 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)
本文标签: riverpodChanging app theme in flutter resets the whole app stateStack Overflow
版权声明:本文标题:riverpod - Changing app theme in flutter resets the whole app state - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742122145a2421763.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论