Skip to content

Instantly share code, notes, and snippets.

@KDCinfo
Last active October 16, 2023 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KDCinfo/6c0e76ba87c4aa2f907e56e97971b261 to your computer and use it in GitHub Desktop.
Save KDCinfo/6c0e76ba87c4aa2f907e56e97971b261 to your computer and use it in GitHub Desktop.
Flutter - GoRouter - themeMode

Flutter

GoRouter

Issue:

A change to the themeMode property rebuilds the routerConfig, which replaces the routing stack with the initialLocation.

Specs:

Flutter 3.16.0-0.1.pre • channel beta • https://github.com/flutter/flutter.git Framework • revision f0abad66b2 (3 days ago) • 2023-10-10 19:29:41 -0700 Engine • revision 7ccdde78a7 Tools • Dart 3.2.0 (build 3.2.0-210.1.beta) • DevTools 2.28.1

environment:
  sdk: '>=3.2.0-210.1.beta <4.0.0'

dependencies:
  equatable: ^2.0.5
  flutter:
    sdk: flutter
  go_router: ^11.1.4
  provider: ^6.0.5
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
/// Update: Swapped out bloc with provider.
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
static final navigatorKey = GlobalKey<NavigatorState>();
GoRouter buildRouter({
required AuthModel authModel,
}) {
return GoRouter(
navigatorKey: navigatorKey,
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => const ScreenHome(),
),
GoRoute(
path: '/auth',
builder: (context, state) => const ScreenAuth(),
),
GoRoute(
path: '/prefs',
builder: (context, state) => const ScreenPrefs(),
),
],
redirect: (context, nextState) {
return !authModel.isAuth
? '/auth'
: nextState.fullPath == '/auth'
? '/'
: null;
},
);
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => AuthModel(),
child: Builder(builder: (context) {
return MaterialApp.router(
routerConfig: buildRouter(
authModel: context.watch<AuthModel>(),
),
title: 'App Title',
theme: ThemeData(
brightness: Brightness.light,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
themeMode:
context.select((AuthModel model) => model.isDark) ? ThemeMode.dark : ThemeMode.light,
);
}),
);
}
}
class AuthModel extends ChangeNotifier {
bool isAuth = false;
bool isDark = false;
void toggleAuth() {
isAuth = !isAuth;
notifyListeners();
}
void toggleDark() {
isDark = !isDark;
notifyListeners();
}
}
class ScreenAuth extends StatelessWidget {
const ScreenAuth({super.key});
@override
Widget build(BuildContext context) {
final authModel = context.watch<AuthModel>();
return Scaffold(
appBar: AppBar(
title: Text('Screen: [Auth] - isAuth: ${authModel.isAuth}'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Text('Auth Screen', style: TextStyle(fontWeight: FontWeight.bold)),
),
ElevatedButton(
onPressed: () {
authModel.toggleAuth();
},
child: const Text('Log in'),
),
],
),
),
);
}
}
class ScreenHome extends StatelessWidget {
const ScreenHome({super.key});
@override
Widget build(BuildContext context) {
final authModel = context.watch<AuthModel>();
return Scaffold(
appBar: AppBar(
title: Text('Screen: [Home] - isAuth: ${authModel.isAuth}'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Text('Home Screen', style: TextStyle(fontWeight: FontWeight.bold)),
),
ElevatedButton(
onPressed: () {
context.push('/prefs');
},
child: const Text('Go to Screen Prefs'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
authModel.toggleDark();
},
child: const Text('Toggle Dark Mode'),
),
],
),
),
);
}
}
class ScreenPrefs extends StatelessWidget {
const ScreenPrefs({super.key});
@override
Widget build(BuildContext context) {
final authModel = context.watch<AuthModel>();
return Scaffold(
appBar: AppBar(
title: Text('Screen: [Prefs] - isAuth: ${authModel.isAuth}'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Text('Prefs Screen', style: TextStyle(fontWeight: FontWeight.bold)),
),
ElevatedButton(
onPressed: () {
authModel.toggleDark();
},
child: const Text('Toggle Dark Mode'),
),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment