Flutter set theme from a list

Flutter set theme from a list
typescript
Ethan Jackson

I am trying to add a list of theme that user can chose one here is my list

import 'package:flutter/material.dart'; class ThemeModel { final Color surface; final Color primary; final Color secondary; final Color onSurface; ThemeModel({ required this.surface, required this.primary, required this.secondary, required this.onSurface, }); } final List<ThemeModel> themes = [ ThemeModel( surface: Color(0xFFF0EAD6), primary: Color(0xFF6C9A8B), secondary: Color(0xFFA67C52), onSurface: Color(0xFF3B3A36), ), ThemeModel( surface: Color(0xFFF5F5F5), primary: Color(0xFF6D6875), secondary: Color(0xFFFFB4A2), onSurface: Color(0xFF2D2D2D), ), ThemeModel( surface: Color(0xFFF0F8FF), primary: Color(0xFFA2C7E5), secondary: Color(0xFF89B0AE), onSurface: Color(0xFF2F3E46), ), ];

I'll show a list and they can chose one that will save a number like chosenTheme now i have a ThemeData like this

ThemeData myTheme = ThemeData( fontFamily: 'estedad', useMaterial3: true, //brightness: chosenTheme <= 2 ? Brightness.light : Brightness.dark, colorScheme: chosenTheme <= 2 ? ColorScheme.light( surface: cards[chosenTheme].themes.surface, primary: cards[chosenTheme].themes.primary, secondary: cards[chosenTheme].themes.secondary, onSurface: cards[chosenTheme].themes.onSurface, ) : ColorScheme.dark( surface: cards[chosenTheme].themes.surface, primary: cards[chosenTheme].themes.primary, secondary: cards[chosenTheme].themes.secondary, onSurface: cards[chosenTheme].themes.onSurface, ), );

how can i set this as apps default theme in a theme provider?

Answer

Create a ThemeProvider class:

import 'package:provider/provider.dart'; class ThemeProvider with ChangeNotifier { int _chosenTheme = 0; // default theme int get chosenTheme => _chosenTheme; set chosenTheme(int value) { _chosenTheme = value; notifyListeners(); } ThemeData get themeData { final theme = themes[_chosenTheme]; // import themes list return ThemeData( fontFamily: 'estedad', useMaterial3: true, colorScheme: _chosenTheme <= 2 ? ColorScheme.light( surface: theme.surface, primary: theme.primary, secondary: theme.secondary, onSurface: theme.onSurface, ) : ColorScheme.dark( surface: theme.surface, primary: theme.primary, secondary: theme.secondary, onSurface: theme.onSurface, ), ); } }

Use ThemeProvider's Consumer inside MyApp Widget and provide themeData to MaterialApp:

import 'package:flutter/material.dart'; class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return Consumer<ThemeProvider>( builder: (context, themeProvider, _) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Themed App', theme: themeProvider.themeData, home: const HomeScreen(), ); }, ); } }

Create a List to update selected theme:

class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context) { final themeProvider = Provider.of<ThemeProvider>(context); return Scaffold( appBar: AppBar(title: const Text("Choose a Theme")), body: ListView.builder( itemCount: themes.length, itemBuilder: (context, index) { final theme = themes[index]; return ListTile( title: Text("Theme ${index + 1}"), tileColor: theme.surface, textColor: theme.onSurface, onTap: () { themeProvider.chosenTheme = index; }, ); }, ), ); } }

Now, Whenever theme is updated by the user it will update the widget tree with the new themeData. Use SharedPreferences to persist the chosenTheme in ThemeProvider.

Related Articles