Je souhaite créer une application flottante qui a 2 thèmes en mode clair et sombre qui changent par un commutateur dans l'application et le thème par défaut est le thème Android par défaut.
J'ai besoin de passer une couleur personnalisée à l'autre widget et je ne veux pas simplement configurer le thème matériel.
5 Réponses :
Widget build(BuildContext context) { var themeData = Theme.of(context).copyWith(scaffoldBackgroundColor: darkBlue) return Scaffold( backgroundColor = themeData.scaffoldBackgroundColor, ); }
C'est un exemple de gestion d'état dans flutter, il existe également un package de fournisseur et flutter_bloc. Pour répondre à la manière de le faire est une question très large, vous pouvez peut-être trouver des tutoriels à ce sujet
MaterialApp( title: 'App Title', theme: ThemeData( brightness: Brightness.light, /* light theme settings */ ), darkTheme: ThemeData( brightness: Brightness.dark, /* dark theme settings */ ), themeMode: ThemeMode.dark, /* ThemeMode.system to follow system theme, ThemeMode.light for light theme, ThemeMode.dark for dark theme */ debugShowCheckedModeBanner: false, home: YourAppHomepage(), ); You can use scoped_model for seamless experience.
À mon avis, le moyen le plus simple consiste à utiliser un fournisseur pour gérer l'état de votre application et shared_preferences pour enregistrer vos préférences de thème sur le système de fichiers. En suivant cette procédure, vous pouvez enregistrer votre thème afin que l'utilisateur n'ait pas à changer de thème à chaque fois.
Vous pouvez facilement stocker votre préférence de thème sous la forme d'une chaîne, puis au début de votre application, vérifiez s'il y a une valeur stockée sur le système de fichiers, si c'est le cas, appliquez ce thème comme indiqué ci-dessous.
StorageManager.dart
void main() { return runApp(ChangeNotifierProvider<ThemeNotifier>( create: (_) => new ThemeNotifier(), child: MyApp(), )); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer<ThemeNotifier>( builder: (context, theme, _) => MaterialApp( theme: theme.getTheme(), home: Scaffold( appBar: AppBar( title: Text('Hybrid Theme'), ), body: Row( children: [ Container( child: FlatButton( onPressed: () => { print('Set Light Theme'), theme.setLightMode(), }, child: Text('Set Light Theme'), ), ), Container( child: FlatButton( onPressed: () => { print('Set Dark theme'), theme.setDarkMode(), }, child: Text('Set Dark theme'), ), ), ], ), ), ), ); } }
Définissez les propriétés de votre thème dans une variable de thème comme ci-dessous et initialisez votre variable _themedata en fonction de la valeur dans le stockage.
ThemeManager.dart
import 'package:flutter/material.dart'; import '../services/storage_manager.dart'; class ThemeNotifier with ChangeNotifier { final darkTheme = ThemeData( primarySwatch: Colors.grey, primaryColor: Colors.black, brightness: Brightness.dark, backgroundColor: const Color(0xFF212121), accentColor: Colors.white, accentIconTheme: IconThemeData(color: Colors.black), dividerColor: Colors.black12, ); final lightTheme = ThemeData( primarySwatch: Colors.grey, primaryColor: Colors.white, brightness: Brightness.light, backgroundColor: const Color(0xFFE5E5E5), accentColor: Colors.black, accentIconTheme: IconThemeData(color: Colors.white), dividerColor: Colors.white54, ); ThemeData _themeData; ThemeData getTheme() => _themeData; ThemeNotifier() { StorageManager.readData('themeMode').then((value) { print('value read from storage: ' + value.toString()); var themeMode = value ?? 'light'; if (themeMode == 'light') { _themeData = lightTheme; } else { print('setting dark theme'); _themeData = darkTheme; } notifyListeners(); }); } void setDarkMode() async { _themeData = darkTheme; StorageManager.saveData('themeMode', 'dark'); notifyListeners(); } void setLightMode() async { _themeData = lightTheme; StorageManager.saveData('themeMode', 'light'); notifyListeners(); } }
Enveloppez votre application avec themeProvider, puis appliquez le thème à l'aide du consommateur. Ce faisant, chaque fois que vous modifiez la valeur du thème et appelez les widgets d'écoute de notification à se reconstruire pour synchroniser les modifications.
Main.dart
import 'package:shared_preferences/shared_preferences.dart'; class StorageManager { static void saveData(String key, dynamic value) async { final prefs = await SharedPreferences.getInstance(); if (value is int) { prefs.setInt(key, value); } else if (value is String) { prefs.setString(key, value); } else if (value is bool) { prefs.setBool(key, value); } else { print("Invalid Type"); } } static Future<dynamic> readData(String key) async { final prefs = await SharedPreferences.getInstance(); dynamic obj = prefs.get(key); return obj; } static Future<bool> deleteData(String key) async { final prefs = await SharedPreferences.getInstance(); return prefs.remove(key); } }
Voici le lien vers le référentiel github.
Capture d'écran:
Vous pouvez utiliser le fournisseur pour définir le thème. Voici le code complet:
bool isDarkMode = SchedulerBinding.instance.window.platformBrightness == Brightness.dark;
Répondre aux questions du PO:
Le thème actuel peut être trouvé en utilisant:
bool isDarkMode = MediaQuery.of(context).platformBrightness == Brightness.dark;
ou
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider<ThemeModel>( create: (_) => ThemeModel(), child: Consumer<ThemeModel>( builder: (_, model, __) { return MaterialApp( theme: ThemeData.light(), // Provide light theme. darkTheme: ThemeData.dark(), // Provide dark theme. themeMode: model.mode, // Decides which theme to show. home: Scaffold( appBar: AppBar(title: Text('Light/Dark Theme')), body: RaisedButton( onPressed: () => model.toggleMode(), child: Text('Toggle Theme'), ), ), ); }, ), ); } } class ThemeModel with ChangeNotifier { ThemeMode _mode; ThemeMode get mode => _mode; ThemeModel({ThemeMode mode = ThemeMode.light}) : _mode = mode; void toggleMode() { _mode = _mode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; notifyListeners(); } }
Vous pouvez fournir un thème à toute votre application en utilisant le theme
pour les thèmes par défaut, darkTheme
pour les thèmes sombres (si le mode sombre est activé par le système ou par vous à l'aide de themeMode
)
Vous pouvez utiliser le package du fournisseur comme indiqué dans le code ci-dessus.
Meilleure réponse!!!.
Capture d'écran:
Si vous ne souhaitez pas utiliser de packages ou de plugins tiers, vous pouvez utiliser ValueListenableBuilder
qui est livré avec Flutter.
Code complet:
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final _notifier = ValueNotifier<ThemeModel>(ThemeModel(ThemeMode.light)); @override Widget build(BuildContext context) { return ValueListenableBuilder<ThemeModel>( valueListenable: _notifier, builder: (_, model, __) { final mode = model.mode; return MaterialApp( theme: ThemeData.light(), // Provide light theme. darkTheme: ThemeData.dark(), // Provide dark theme. themeMode: mode, // Decides which theme to show. home: Scaffold( appBar: AppBar(title: Text('Light/Dark Theme')), body: RaisedButton( onPressed: () => _notifier.value = ThemeModel(mode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light), child: Text('Toggle Theme'), ), ), ); }, ); } } class ThemeModel with ChangeNotifier { final ThemeMode _mode; ThemeMode get mode => _mode; ThemeModel(this._mode); }
Vous ai-je bien compris, vous avez 3 thèmes, un mode clair, un mode sombre et un thème Android par défaut? L'utilisateur peut-il basculer entre le thème du mode clair et sombre? Que voulez-vous dire exactement par le
need to pass some custom color to the fellow widget
?non, j'ai le mode sombre et le mode clair en contournant uniquement la couleur.Je veux dire que j'ai 2 couleurs blanc et gris pour l'arrière-plan et la bordure dans le widget, donc à la place, si vous écrivez l'
background:Colors.white
je veux l'background:store.xColor
-background:store.xColor
Vérifiez ma réponse ci-dessous, vous devez utiliser ThemeMode.system pour détecter le thème du système.