Flutter - Material3适配

demo 地址: https://github.com/iotjin/jh_flutter_demo
代码不定时更新,请前往github查看最新代码

Flutter - Material3适配

Material3适配官方文档

flutter SDK升级到3.16.0之后 ThemeData()useMaterial3属性如果不设置默认为true,这时运行项目会发现有些UI效果和之前有点不一样,如果原本使用的是默认的主题色,此时会发现主题色已经发生变化,因为Material3的默认主题不再是蓝色,变成了紫色。
如果不想使用Material3直接设置useMaterial3: false即可

对比图

以下图片中的一些组件已经做了适配如FloatingActionButton按钮、TextField的边框等,方便对比展示效果,具体请查看代码

Material2 Material3

具体实现

Material3适配官方文档

  • Material3适配主要通过ThemeData实现的
  • 在demo中,一部分常用的组件都有抽出来的公用组件,一般情况把组件适配一下通过使用公用组件可以避免直接设置ThemeData带来的问题。当然直接设置ThemeData也可以
  • 设置 ThemeData(ThemeData(useMaterial3: true, ...) 使用 Material3

其中最重要的是设置主色调,在 Material3 中官方推荐通过 colorScheme: ColorScheme.fromSeed设置主色调,当然通过 ColorScheme.fromSwatch()也可以设置,不过可能需要多配置点东西

其余的就是一些组件的设置了

一些组件的变化

  • Text() 样式调整
  • TextButton()、ElevatedButton()、OutlinedButton()等 风格变化,更圆润
  • FloatingActionButton()形状从圆形变成矩形
  • Switch() UI变化
  • Card()背景色
  • AppBar()底部阴影、图标颜色等
  • BottomNavigationBar()水波纹效果变化
  • TabBar()底部线
    ...

代码实现

以下是通过ThemeData()设置整个项目的,对应demo的全局主题设置文件getThemeData()函数

根据需要打开并配置, 如果有基础组件也可以针对组件单独配置

单个适配或对比详见 demo代码UITest3文件

Material2的ThemeData

dart 复制代码
  static _m2ThemeData(Color themeColor, {bool isDarkMode = false}) {
    // 暗黑模式高亮显示颜色
    var darkPrimaryThemeColor = KColors.kThemeColor;

    return ThemeData(
      useMaterial3: false,
      primarySwatch: JhColorUtils.materialColor(themeColor),
      primaryColor: themeColor,
      colorScheme: ColorScheme.fromSwatch().copyWith(
        brightness: isDarkMode ? Brightness.dark : Brightness.light,
        secondary: isDarkMode ? KColors.kThemeDarkColor : themeColor,
        // surfaceTint: Colors.transparent, // 影响 card 的配色,M3下是applySurfaceTint
        // outline: Colors.grey, // M3 设置OutlinedButton、TextField 边框颜色(尽量单独设置) , Color(0xff79747e)
      ),
      // 页面背景色
      scaffoldBackgroundColor: isDarkMode ? KColors.kBgDarkColor : KColors.kBgColor,
      // 导航条在base_appbar页面配置(没使用base_appbar的按下面配置的)
      appBarTheme: AppBarTheme(
        systemOverlayStyle: JhStatusBarUtils.getStatusBarStyle(isDark: isDarkMode),
        color: isDarkMode ? KColors.kNavBgDarkColor : themeColor,
        iconTheme: const IconThemeData(color: Colors.white),
        // shadowColor: Colors.grey, // M3 设置阴影颜色
      ),
      // 主界面tabbar,在base_tabbar页面配置
      // bottomNavigationBarTheme: BottomNavigationBarThemeData(
      //   backgroundColor: Colors.white,
      //   selectedItemColor: KColors.kTabBarSelectTextColor,
      //   unselectedItemColor: KColors.kTabBarNormalTextColor,
      // ),
      // 分割线
      dividerTheme: DividerThemeData(color: isDarkMode ? KColors.kLineDarkColor : KColors.kLineColor),
      // Tab指示器颜色
      indicatorColor: isDarkMode ? darkPrimaryThemeColor : themeColor,
      // 文字选择色(输入框选择文字等)
      textSelectionTheme: TextSelectionThemeData(
        selectionColor: isDarkMode ? darkPrimaryThemeColor.withAlpha(70) : themeColor.withAlpha(70),
        selectionHandleColor: isDarkMode ? darkPrimaryThemeColor : themeColor,
        cursorColor: isDarkMode ? darkPrimaryThemeColor : themeColor, // 光标
      ),

      // 主要用于Material背景色
      // canvasColor: isDarkMode ? KColors.kMaterialBgDarkColor : KColors.kMaterialBgColor,
      // errorColor: isDarkMode ? KColors.kErrorTextDarkColor : KColors.kErrorTextColor,
      // cupertinoOverrideTheme: CupertinoThemeData(
      //   brightness: isDarkMode ? Brightness.dark : Brightness.light,
      // ),
      // visualDensity: VisualDensity.standard,
    );
  }

Material3的ThemeData

dart 复制代码
  static _m3ThemeData(Color themeColor, {bool isDarkMode = false}) {
    // 暗黑模式高亮显示颜色
    var darkPrimaryThemeColor = KColors.kThemeColor;

    return ThemeData(
      useMaterial3: true,
      primarySwatch: JhColorUtils.materialColor(themeColor),
      primaryColor: themeColor,
      // 页面背景色
      scaffoldBackgroundColor: isDarkMode ? KColors.kBgDarkColor : KColors.kBgColor,
      // 导航条在base_appbar页面配置(没使用base_appbar的按下面配置的)
      appBarTheme: AppBarTheme(
        systemOverlayStyle: JhStatusBarUtils.getStatusBarStyle(isDark: isDarkMode),
        color: isDarkMode ? KColors.kNavBgDarkColor : themeColor,
        iconTheme: const IconThemeData(color: Colors.white),
        // shadowColor: Colors.grey, // M3 设置阴影颜色
      ),
      // 主界面tabbar,在base_tabbar页面配置
      // bottomNavigationBarTheme: BottomNavigationBarThemeData(
      //   backgroundColor: Colors.white,
      //   selectedItemColor: KColors.kTabBarSelectTextColor,
      //   unselectedItemColor: KColors.kTabBarNormalTextColor,
      // ),
      // 分割线
      dividerTheme: DividerThemeData(color: isDarkMode ? KColors.kLineDarkColor : KColors.kLineColor),
      // Tab指示器颜色
      indicatorColor: isDarkMode ? darkPrimaryThemeColor : themeColor,
      // 文字选择色(输入框选择文字等)
      textSelectionTheme: TextSelectionThemeData(
        selectionColor: isDarkMode ? darkPrimaryThemeColor.withAlpha(70) : themeColor.withAlpha(70),
        selectionHandleColor: isDarkMode ? darkPrimaryThemeColor : themeColor,
        cursorColor: isDarkMode ? darkPrimaryThemeColor : themeColor, // 光标
      ),

      // 主要用于Material背景色
      // canvasColor: isDarkMode ? KColors.kMaterialBgDarkColor : KColors.kMaterialBgColor,
      // errorColor: isDarkMode ? KColors.kErrorTextDarkColor : KColors.kErrorTextColor,
      // cupertinoOverrideTheme: CupertinoThemeData(
      //   brightness: isDarkMode ? Brightness.dark : Brightness.light,
      // ),
      // visualDensity: VisualDensity.standard,

      /// ------------------------------ Material3适配 ------------------------------
      /// https://docs.flutter.dev/release/breaking-changes/material-3-migration
      /// 一些调整适配详见 UITest3
      /// 根据需要打开并配置, 如果有基础组件也可以针对组件单独配置

      /// M3设置主题色 方式一
      colorScheme: ColorScheme.fromSeed(
        seedColor: isDarkMode ? darkPrimaryThemeColor : themeColor,
        brightness: isDarkMode ? Brightness.dark : Brightness.light,
        surfaceTint: Colors.transparent, // 影响 card 的配色,M3下是applySurfaceTint
        // outline: Colors.grey, // M3 设置OutlinedButton、TextField、Switch 边框颜色(尽量单独设置) , Color(0xff79747e)
      ),

      /// M3设置主题色 方式二
      // colorScheme: ColorScheme.fromSwatch().copyWith(
      //   brightness: isDarkMode ? Brightness.dark : Brightness.light,
      //   secondary: isDarkMode ? KColors.kThemeDarkColor : themeColor,
      //   surfaceTint: Colors.transparent, // 影响 card 的配色,M3下是applySurfaceTint
      //   // outline: Colors.grey, // M3 设置OutlinedButton、TextField 边框颜色(尽量单独设置) , Color(0xff79747e)
      // ),
      // textTheme: TextTheme(
      //   bodyMedium: TextStyle(color: isDarkMode ? KColors.kBlackTextDarkColor : KColors.kBlackTextColor),
      // ),
      // textButtonTheme: TextButtonThemeData(
      //   style: TextButton.styleFrom(
      //     // side: BorderSide(width: 1.0, color: themeColor), // 设置边框
      //     shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0)), // 设置圆角
      //     splashFactory: InkSplash.splashFactory, // 设置水波纹
      //   ),
      // ),
      // outlinedButtonTheme: OutlinedButtonThemeData(
      //   style: ButtonStyle(side: MaterialStateProperty.all(BorderSide(color: themeColor))),
      // ),
      // floatingActionButtonTheme: FloatingActionButtonThemeData(
      //   backgroundColor: themeColor,
      //   foregroundColor: Colors.white,
      //   shape: CircleBorder(), // 浮动按钮设成圆形
      // ),
      // progressIndicatorTheme: ProgressIndicatorThemeData(
      //   refreshBackgroundColor: isDarkMode ? KColors.kMaterialBgDarkColor : KColors.kMaterialBgColor, // 下拉刷新MaterialHeader()背景色适配
      //
      //   // color: Colors.purpleAccent, // 设置进度指示器的颜色
      //   // linearTrackColor: Colors.black, // 设置线性进度指示器的背景颜色
      //   // linearMinHeight: 4.0, // 设置线性进度指示器的最小高度
      //   // circularTrackColor: Colors.green, // 设置圆形进度指示器的背景颜色
      //   // refreshBackgroundColor: Colors.orange, // 设置刷新指示器的背景颜色
      // ),
      // tabBarTheme: TabBarTheme(
      //   dividerColor: Colors.grey[400],
      //   dividerHeight: 0.5,
      // ),
      // BottomNavigationBar()点击水波纹样式变更,通过Theme() 设置splashFactory: InkSplash.splashFactory
    );
  }
相关推荐
阿笑带你学前端1 小时前
Flutter本地通知系统:记账提醒的深度实现
前端·flutter
孤鸿玉20 小时前
Fluter InteractiveViewer 与ScrollView滑动冲突问题解决
flutter
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
BG2 天前
Flutter 简仿Excel表格组件介绍
flutter
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
恋猫de小郭2 天前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
卡尔特斯2 天前
Flutter A GlobalKey was used multipletimes inside one widget'schild list.The ...
flutter
w_y_fan2 天前
Flutter 滚动组件总结
前端·flutter
醉过才知酒浓2 天前
Flutter Getx 的页面传参
flutter
火柴就是我3 天前
flutter 之真手势冲突处理
android·flutter