I’m trying to make an option on my app to allow the user to choose between a light theme, a dark theme or just leave the theme to match the one on their phone’s preferences, that is, if they have a dark appearance and the user selects the option it will match the phone’s appearance.
What I have right now is:
- My Provider which looks like this:
class ThemeChanger with ChangeNotifier {
ThemeData _themeData;
ThemeChanger(this._themeData);
getTheme() => _themeData;
setTheme( ThemeData theme) {
this._themeData = theme;
notifyListeners();
}
}
- My home.dart, where I have the basics to work with the view and looks like this
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
body: const ButtonsList(),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.ads_click),
onPressed: (){}),
);
}
}
class ButtonsList extends StatelessWidget {
const ButtonsList({super.key});
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeChanger>(context);
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
child: Icon(Icons.sunny),
onPressed: () => theme.setTheme(ThemeData.light())
),
SizedBox(width: 20,),
FloatingActionButton(
child: Icon(Icons.dark_mode),
onPressed: () => theme.setTheme(ThemeData.dark())
),
SizedBox(width: 20,),
FloatingActionButton(
child: Icon(Icons.settings),
onPressed: (){} //should pick the system theme
),
],
),
);
}
}
- And finally my main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tema_provider/blocs/theme.dart';
import 'package:tema_provider/pages/home.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: ( _ ) => ThemeChanger( ThemeData.light() ),
child: MaterialAppWithTheme(),
);
}
}
class MaterialAppWithTheme extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeChanger>(context);
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: theme.getTheme(),
home: HomePage()
);
}
}
One of the problems I have is that I know the system’s theme can be access with the themeMode.system
but in my code I’m working with ThemeData
, I’ve tried changing the code on my 1st block of code and work with ThemeMode
instead because it also has dark and light modes but it didn’t work.
I don’t know if what I’m trying to do is possible, all I’ve found so far is switch between dark/light mode which the app does with the code as it is.
Any help/indication/link to a resource is highly appreciated 🙂
2
Answers
What I understand from your question is you want to access system theme but you are using theme data.
Here is the solution I’m using for my application.
Now to listen live theme changes in app from OS you can implement below things.
Let me know if you are still not able to figure out the issue.
here, your approach is wrong.
MaterialApp has theme and darkTheme property, and flutter uses theme when themeMode is ThemeMode.light and use darkTheme when themeMode is ThemeMode.dark.
So that, it will be standard if you change the themeMode for changing the theme of Futter App.
when themeMode is ThemeMode.system then the Flutter app’s theme will change (listening) on OS theme mode auto.
here is how I do this,
If you have any confusion on the implementation feel free to ask please.