How can I check if dark mode is enabled in Android Q with Flutter?
I know how to set the dark mode, but I didn't find a way to check the background theme.
Here is the code to set the dark theme.
darkTheme: ThemeData.dark(),
There are two ways:
NO context required. Can be used in initState for example:
var brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
bool isDarkMode = brightness == Brightness.dark;
context is required:
var brightness = MediaQuery.of(context).platformBrightness;
bool isDarkMode = brightness == Brightness.dark;
or
var brightness = View.of(context).platformDispatcher.platformBrightness;
bool isDarkMode = brightness == Brightness.dark;
build() method, and if the crashes again, please post the stack trace because it is working for me.MediaQuery.of(context).platformBrightness, can we use Theme.of(context).brightness. Is there any difference here?With the introduction of Extension methods in Dart, I prefer to append that functionality to BuildContext directly. This provides a cleaner feeling interface and reads much better.
import 'dart:ui';
import 'package:flutter/widgets.dart';
extension DarkMode on BuildContext {
/// is dark mode currently enabled?
bool get isDarkMode {
final brightness = MediaQuery.of(this).platformBrightness;
return brightness == Brightness.dark;
}
}
Then in my build functions I can use it easily.
@override
Widget build(BuildContext context) {
final Widget logo = SvgPicture.asset(
context.isDarkMode ? "assets/logo_dark.svg" : "assets/logo.svg",
semanticsLabel: 'my logo');
}
I found the way. Here it is.
bool _darkModeEnabled = false;
void _checkIfDarkModeEnabled() {
final ThemeData theme = Theme.of(context);
theme.brightness == appDarkTheme().brightness
? _darkModeEnabled = true
: _darkModeEnabled = false;
}
Update 27.02.23:
final brightness = WidgetsBinding.instance.platformDispatcher.platformBrightness;
Theme object, one is you fetch the theme applied in Phone settings (available only in Android Pie dark mode), for this you use MediaQuery.MaterialApp has 3 related properties: theme, darkTheme and themeMode. If themeMode is not system or darkTheme is null, then the brightness of the app's theme will be light even if the OS (Android 10+/iOS 13+) has dark mode enabled. @CopsOnRoad has the correct answer.If you define a dark theme in your MaterialApp, your app will automatically go dark when Android Q dark theme is enabled. You have to specify your dark theme like this:
MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.red,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
);
According to this medium article,
Now when you toggle Dark Theme in your system drawer, your Flutter app will automatically switch from your regular theme to your darkTheme!
However, if you want to manually check whether you're on dark mode, you can easily write a method using the Platform Channel API. More details here. As for the native code, check here.
How can I check if dark mode is enabled
Answer:
Theme.of(context).brightness == Brightness.dark
You can use ThemeMode inside MaterialApp.
MaterialApp(
themeMode: ThemeMode.system,
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.red,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
);
ThemeMode.system will get the active theme in the OS and then either use the theme or darkTheme. Additionally ThemeMode.dark will always use the darkTheme and ThemeMode.light will always use the theme.
No matter what the current platform is, if you have access to context you can simply check it by using Theme. Following is sample that I used to change white color to transparent color if currently app theme is dark.
(Theme.of(context) == Brightness.dark) ? Colors.white : Colors.transparent
Try the following code
Brightness brightness = Theme.of(context).brightness
bool isDarkMode = brightness == Brightness.dark;
bool isLightMode = brightness == Brightness.light;
If you are using Getx state management, then don't worry because Getx provided solution
bool ThemeModes(){
Get.isDarkMode? return true: return false;}
Check OS theme mode: (if using ThemeMode.system)
Brightness brightness = MediaQueryData.fromWindow(WidgetsBinding.instance.window).platformBrightness;
bool darkModeOn = brightness == Brightness.dark;
or using theme
Brightness brightness = Theme.of(context).brightness
bool darkModeOn = brightness == Brightness.dark;
set brightness in MaterialApp
theme: ThemeData(
brightness: Brightness.light,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
Please notice that MediaQuery.of(context).platformBrightness will cause rebuilding on all media queries events including screen size changed, rotation, popup keyboard, ...
Instead, MediaQuery.platformBrightnessOf only rebuild when system dark mode changes:
final brightness = MediaQuery.platformBrightnessOf(context);
final systemDarkMode = brightness == Brightness.dark;
bool _darkModeEnabled = false;
bool _lightModeEnabled = false;
void _checkIfDarkModeEnabled() {
final ThemeData theme = Theme.of(context);
theme.brightness == Brightness.dark
? _darkModeEnabled = true
: _darkModeEnabled = false;
}
void _checkIfLightModeEnabled() {
final ThemeData theme = Theme.of(context);
theme.brightness == Brightness.light
? _lightModeEnabled = true
: _lightModeEnabled = false;
}
I'm using https://github.com/arthurdenner/theme_mode_handler, and the right way to check if it's set on system first, otherwise we check the theme handler:
bool is_dark(BuildContext context){
if(ThemeModeHandler.of(context)!.themeMode == ThemeMode.system)
return (Theme.of(context).brightness == Brightness.dark);
else
return ThemeModeHandler.of(context)!.themeMode == ThemeMode.dark;
}
Accepted answer is absolutely right.
I just try to give answer with different approach.
first how you know your system theme-mode (like it's dark-mode or light mode)
final brightness = MediaQuery.of(context).platformBrightness;
final brightness2 = MediaQuery.platformBrightnessOf(context);
final brightness3 = SchedulerBinding.instance.platformDispatcher.platformBrightness;
final brightness4 = View.of(context).platformDispatcher.platformBrightness;
This all variable brightness, brightness2, brightness3 and brightness4 give same value of Brightness Class
But i Highly recommend go through MediaQuery.of(context).platformBrightness
Now You can used this variable to get your system theme-mode and change your app theme base this.
Little-More
I make extension method for getting bool value like this way
Note : You can absolutely do without this method
extension IsDarkMode on Brightness {
//! Way1
bool get isDark => index == 0;
bool get isLight => index == 1;
//! Way2
bool get isDark2 => this == Brightness.dark;
bool get isLight2 => this == Brightness.light;
}
Reference Code
// Please Ignore MultiProvider and routes
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final brightness = MediaQuery.of(context).platformBrightness;
// final brightness = MediaQuery.platformBrightnessOf(context);
// final brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
// final brightness = View.of(context).platformDispatcher.platformBrightness;
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => HomeProvider()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'AI Video',
routes: routes,
initialRoute: RoutePath.splash,
theme: AppTheme.instance.lightTheme, // your light theme data
darkTheme: AppTheme.instance.darkTheme, // your dark theme data
//! Applied Dark/Light Theme here base on system theme
// themeMode: brightness.isLight ? ThemeMode.light : ThemeMode.dark,
themeMode: brightness.isLight2 ? ThemeMode.light : ThemeMode.dark,
),
);
}
}