Reputation: 2117
In my flutter app, I allow user to change the theme of the app using either Follow System
, Light
or Dark
theme.
But the status bar color doesn't change appropriately. My status bar icon color always stays white (Which means when set to light theme, it becomes invisible).
I even tried the below which didn't work:
// Determine the app brightness (theme)
final brightness = PlatformDispatcher.instance.platformBrightness;
print("Brightness: $brightness");
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarIconBrightness: brightness == Brightness.dark
? Brightness.light
: Brightness.dark, // status bar color
));
I then realized this through my print log:
Irrespective of my app theme, when the system UI (in my phone settings) itself is set to light theme, whether i choose follow_system, light or dark in my app, it always returns Brightness.Light and when the system UI itself is set to dark theme, it always returns Brightness.Dark
Is this a normal behavior or am i doing something wrong ?
Below is just a reference how i initialize my MaterialApp:
ThemeData light() {
return theme(const ColorScheme(
brightness: Brightness.light,
primary: ....,
)
)
ThemeData dark() {
return theme(const ColorScheme(
brightness: Brightness.dark,
primary: ....,
)
)
ThemeData lightHighContrast() {
return theme(const ColorScheme(
brightness: Brightness.light,
primary: ....,
)
)
ThemeData darkHighContrast() {
return theme(const ColorScheme(
brightness: Brightness.dark,
primary: ....,
)
)
ThemeData theme(ColorScheme colorScheme) => ThemeData(
useMaterial3: true,
brightness: colorScheme.brightness,
colorScheme: colorScheme,
appBarTheme: appBarTheme,
textTheme: textTheme.apply(
bodyColor: colorScheme.onSurface,
displayColor: colorScheme.onSurface,
),
scaffoldBackgroundColor: colorScheme.surface,
canvasColor: colorScheme.surface,
);
class MesMaterialApp extends ConsumerWidget {
MesMaterialApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// Get the initial location
final intitialLocation =
ref.watch(settingsProvider.select((s) => s.isOnboarded))
? HomeRoute.path
: WelcomeRoute.path;
// Set the initial location
MesAppRouter.instance.setInitialLocation(intitialLocation);
// Get the router instance
final router = MesAppRouter.instance.getRouter();
// Determine the app brightness (theme)
final brightness = PlatformDispatcher.instance.platformBrightness;
print("Brightness: $brightness");
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarIconBrightness: brightness, // status bar icons' color
statusBarColor: brightness == Brightness.dark
? Colors.white
: Colors.black, // status bar color
));
// Create the text theme
TextTheme textTheme = createTextTheme(context, "Poppins", "Lato");
// Create the app bar theme
AppBarTheme appBarTheme = createAppBarTheme(brightness);
// Create the material theme
MaterialTheme theme = MaterialTheme(
textTheme,
appBarTheme,
);
// Return the Material App
return MaterialApp.router(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: theme.light(),
darkTheme: theme.dark(),
highContrastTheme: theme.lightHighContrast(),
highContrastDarkTheme: theme.darkHighContrast(),
themeMode: ref.watch(settingsProvider.select(
(s) => s.theme,
)),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: ref.watch(settingsProvider.select(
(s) => s.locale == MesLocale.system ? null : Locale(s.locale.lang),
)),
routerConfig: router,
);
}
}
Upvotes: 0
Views: 40
Reputation: 160
class BrightnessExample extends StatefulWidget {
const BrightnessExample({super.key});
@override
State<BrightnessExample> createState() => _BrightnessExampleState();
}
class _BrightnessExampleState extends State<BrightnessExample>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
Brightness get platformBrightness {
return WidgetsBinding.instance.platformDispatcher.platformBrightness;
}
@override
void didChangePlatformBrightness() {
super.didChangePlatformBrightness();
// CHANGE SYSTEM STATUS BAR HERE ACCRODINLY WITH PLATFROM BRIGHNESS
}
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
Here’s how you can use the WidgetsBindingObserver mixin to detect platform brightness changes and update the app’s status bar accordingly.
First, add the WidgetsBindingObserver mixin to your State class.
Register the WidgetsBindingObserver in the initState method to start listening for platform changes.
Create a simple getter to fetch the current platform brightness, and override didChangePlatformBrightness to handle brightness changes dynamically.
Upvotes: 0