demo 地址: https://github.com/iotjin/jh_flutter_demo
代码不定时更新,请前往github查看最新代码
Flutter - Material3适配
- 对比图
- 具体实现
- 一些组件的变化
- 代码实现
- Material2的ThemeData
- Material3的ThemeData
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
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
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
);
}