15
votes

comment implémenter le mode sombre en scintillement

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.

  • comment détecter le thème par défaut de l'appareil utilisateur?
  • la deuxième question est de savoir comment fournir un thème à l'ensemble de l'application?
  • Troisièmement, comment changer le thème avec un simple changement de temps d'exécution?

3 commentaires

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.


5 Réponses :


7
votes
Widget build(BuildContext context) {
  var themeData = Theme.of(context).copyWith(scaffoldBackgroundColor: darkBlue)

  return Scaffold(
    backgroundColor = themeData.scaffoldBackgroundColor,
  );
}

1 commentaires

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



16
votes
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.

0 commentaires

6
votes

À 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.

Production entrez la description de l'image ici

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() =&gt; _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.


0 commentaires

1
votes

Capture d'écran:

entrez la description de l'image ici


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.


1 commentaires

Meilleure réponse!!!.



2
votes

Capture d'écran:

entrez la description de l'image ici


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);
}


0 commentaires