Flutter - Material3适配

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

Material3适配官方文档

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

对比图

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

Material2Material3

具体实现

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()底部线
  • Alert()、BottomSheet()等弹框的背景色、圆角、水波纹效果

代码实现

以下是通过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
    );
  }
### Android Material3 使用指南 Material 3 是 Google 推出的新一代设计语言,旨在提供更现代化、灵活的设计框架。以下是关于如何在 Android 应用程序中集成和使用 Material 3 的详细说明。 #### 添加依赖项 为了在项目中启用 Material 3 功能,需先在 `build.gradle` 文件中添加相应的依赖项: ```gradle dependencies { implementation &#39;com.google.android.material:material:<latest_version>&#39; } ``` 最新版本号可以通过官方 GitHub 页面获取[^2]。 #### 配置主题 Material 3 提供了一套全新的颜色体系和组件样式。要切换到 Material 3 主题,可以在项目的 `themes.xml` 中更改根节点的主题属性为以下之一: ```xml <style name="Theme.App.Material3" parent="android:Theme.Material3.DayNight"> </style> ``` 如果需要支持深色模式,则可以定义两个文件分别处理浅色和深色主题逻辑:`themes.xml (light)` 和 `themes.xml(night)`。 #### 自定义颜色方案 Material 3 支持动态调色板功能,允许开发者基于品牌色彩创建一致的颜色体验。这通常涉及调整主色调、次级色调以及其他辅助颜色参数。例如,在 XML 资源文件中自定义颜色如下所示: ```xml <resources> <!-- Primary brand color --> <color name="md_theme_light_primary">@color/your_custom_color</color> <!-- Secondary brand color --> <color name="md_theme_light_secondary">@color/another_custom_color</color> </resources> ``` 以上操作会覆盖默认值并应用于整个应用程序界面。 #### 组件升级 许多经典控件已迁移到符合 M3 规范的新实现形式下工作;比如按钮(Button),现在推荐使用带有 elevated 属性的 ElevatedButton 来代替传统 Button 控制器: ```kotlin import com.google.android.material.button.MaterialButton val button = findViewById<MaterialButton>(R.id.my_button) button.setText("Click Me!") ``` 此外还有其他重要的 UI 元素也进行了相应改造, 如 Snackbar , BottomAppBar 等均提供了更加丰富的交互选项以及视觉效果增强特性[^4]. #### 示例代码片段 下面展示了一个简单的计数器应用例子,它展示了基本布局搭建过程以及部分核心 API 的实际运用情况: ```xml <!-- activity_main.xml --> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/textViewCounter" android:textSize="24sp" android:gravity="center_horizontal" android:paddingTop="16dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <com.google.android.material.button.MaterialButton android:id="@+id/buttonIncrement" android:text="+ Increment" android:onClick="onButtonClick" style="?attr/materialButtonStyle" android:layout_gravity="center_horizontal" android:layout_marginTop="16dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> ``` ```java // MainActivity.java public class MainActivity extends AppCompatActivity { private int countValue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textViewCount = findViewById(R.id.textViewCounter); this.countValue = 0; updateText(textViewCount); } public void onButtonClick(View view){ TextView textViewCount = findViewById(R.id.textViewCounter); ++this.countValue; updateText(textViewCount); } private void updateText(TextView tv){ String textToShow = Integer.toString(this.countValue); tv.setText(textToShow); } } ``` 上述实例演示了如何利用 Material Components 创建一个基础用户界面,并通过点击事件改变显示内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西半球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值