flutter3.0学习笔记

适配暗黑模式

Preview
  • 第一步:安装依赖
  • 第二步:创建一个类SharedPreferences
  • 第三步:创建模型
  • 第四步:设置暗黑样式
  • 第五步:将Provider加入MaterialApp
  • 第六步:编写一个开关按钮

第一步:安装依赖

Provider用于管理在应用程序上实现深色主题时的状态。使用shared_preferences来设置内存中的值,因此即使我们关闭应用程序并重新打开它,我们的数据也不会丢失

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.4
  shared_preferences: ^2.0.15

第二步:创建一个类SharedPreferences

创建了一个类DarkThemePreference,我们在其中存储深色主题的值,写了两个方法分别来保存和获得值。

import 'package:shared_preferences/shared_preferences.dart';

class DarkThemePreference {
  static const THEME_STATUS = "THEMESTATUS";
  setDarkTheme(bool value) async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool(THEME_STATUS, value);
  }

  Future<bool> getTheme() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getBool(THEME_STATUS) ?? false;
  }
}

第三步:创建模型

import 'package:flutter/material.dart';
import 'package:flutter_base/model/DarkThemePreference.dart';

class DarkThemeProvider with ChangeNotifier{
  DarkThemePreference darkThemePreference = DarkThemePreference();
  bool _darkTheme = false;
  bool get darkTheme => _darkTheme;
  set darkTheme(bool value){
    _darkTheme = value;
    darkThemePreference.setDarkTheme(value);
    notifyListeners();
  }
}

第四步:设置暗黑样式

//dark_theme_styles.dart
import 'dart:ui';

import 'package:flutter/material.dart';

class Styles {

  static ThemeData themeData(bool isDarkTheme, BuildContext context) {
    return ThemeData(
      primarySwatch: Colors.blue,
      primaryColor: isDarkTheme ? Colors.black : Colors.white,
      backgroundColor: isDarkTheme ? Colors.black : const Color(0xffF1F5FB),

      indicatorColor: isDarkTheme ? const Color(0xff0E1D36) : const Color(0xffCBDCF8),

      hintColor: isDarkTheme ? const Color(0xff280C0B) : const Color(0xffEECED3),

      highlightColor: isDarkTheme ? const Color(0xff372901) :const Color(0xffFCE192),
      hoverColor: isDarkTheme ? const Color(0xff3A3A3B) : const Color(0xff4285F4),
      focusColor: isDarkTheme ? const Color(0xff0B2512) : const Color(0xffA8DAB5),
      disabledColor: Colors.grey,
      cardColor: isDarkTheme ? const Color(0xFF151515) : Colors.white,
      canvasColor: isDarkTheme ? Colors.black : Colors.grey[50],
      brightness: isDarkTheme ? Brightness.dark : Brightness.light,
      elevatedButtonTheme: ElevatedButtonThemeData(
        style: ButtonStyle(
          backgroundColor:isDarkTheme? MaterialStateProperty.all<Color>(Colors.blueGrey,) : MaterialStateProperty.all<Color>(const Color(0xff4285F4)), //button color
          foregroundColor: MaterialStateProperty.all<Color>(Colors.white), //text (and icon)
        ),
      ),
      buttonTheme: Theme.of(context).buttonTheme.copyWith(
          colorScheme: isDarkTheme ? const ColorScheme.dark() :const ColorScheme.light()),
      appBarTheme:const AppBarTheme(
        elevation: 0.0,
      ), textSelectionTheme: TextSelectionThemeData(selectionColor: isDarkTheme ? Colors.white : Colors.black),
    );
  }
}

第五步:将Provider加入MaterialApp

class _MyAppState extends State<MyApp> {
  DarkThemeProvider themeChangeProvider = DarkThemeProvider();
  @override
  void initState() {
    // TODO: implement initState
    getCurrentAppTheme();
    super.initState();
  }
  void getCurrentAppTheme() async{
    themeChangeProvider.darkTheme = await themeChangeProvider.darkThemePreference.getTheme();
  }
  @override
  Widget build(BuildContext context) {

    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context)=>themeChangeProvider)
      ],
      child: Consumer<DarkThemeProvider>(
        builder: (context,darkModeProvider,child){
          return MaterialApp(
            title: 'Flutter Demo',
            theme: Styles.themeData(themeChangeProvider.darkTheme, context),
            initialRoute: '/',//名为"/"的路由作为应用的home(首页)
            //注册路由
            routes: {
              '/':(context)=> MyHomePage(title: '样式实例入口'),//注册首页路由
            },
          );
        },
      ),
    );
  }
}

第六步:编写一个开关按钮

 final themeProvider = Provider.of<DarkThemeProvider>(context);
//...省略代码...
Positioned(
  right:0,
  top: 0,
  child: GestureDetector(
    onTap: (){
      themeProvider.darkTheme = !themeProvider.darkTheme;
    },
    child: Container(
      height:150,
      width: 50,
      decoration: BoxDecoration(
        borderRadius: const BorderRadius.only(
            bottomLeft: Radius.circular(30),
            bottomRight: Radius.circular(30)
        ),
        shape: BoxShape.rectangle,
        color: Theme.of(context).hoverColor,
      ),
      child: Padding(
        padding: const EdgeInsets.only(left: 12,right: 12,bottom: 28),
        child:themeProvider.darkTheme
            ? Image.asset('images/bulb_off.png',fit: BoxFit.fitHeight,)
            : Image.asset('images/bulb_on.png',fit: BoxFit.fitHeight,)
      ),
    ),
  )
),

theme.gif