Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧

这篇具有很好参考价值的文章主要介绍了Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如果要说 Flutter 3.16 升级里是最坑的是什么?那我肯定要说是 Material 3 default (M3)。

倒不是说 M3 bug 多,也不是 M3 在 3.16 上使用起来多麻烦,因为虽然从 3.16 开始,MaterialApp 里的 useMaterial3 默认会是 true,但是你是可以直接 使用 useMaterial3: false 来关闭

那为什么还收坑?因为未来 Material 2 相关的东西会被弃用并删除,所以 Material 3 default(M3) 是一个警告,你可以通过 useMaterial3: false 来关闭无视,但是这个技术债未来会很坑。

难道你还能一直苟着不更新?

为什么说它很坑?因为适配它纯纯是一个体力活,而且还是一个细节工作,M3 是一套配色方案,一套和 M2 「毫不相关」的配色方案

  • 配色方案代表着它已经帮你默认确定了什么地方应该用什么颜色
  • M2 毫不相干,代表着你之前用这 M2 的 Widget 默认的 UI 效果,用了 M3 会完全不一样

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

如上图所示,看起来好像是就是:

  • AppBar 配色发生了变化
  • FloatingActionButton 从圆的变成方的,颜色发生变化
  • 默认 Button 按照风格发生了变卦
  • ······

似乎看起来也没什么,但是你知道有多少地方用了 FloatingActionButton ?每个地方的 AppBar 难道都要手动去调整?ElevatedButtonTextButton 有没有办法全局配置?本篇就是为了让你少走适配弯路,提供适配思路的角度。

核心还是国内的产品有谁愿意使用 Material Design ? 像这种 M2 到 M3 的变化,对于开发者来说纯粹就是负优化。

开始

首先,官方 Material 3 配色首推是使用 ColorScheme.fromSeed() 来生成配色,当然你也可以通过 ColorScheme.fromImageProvider 的图片来生成配色,不过一般人应该不会这么干,另外还有 ColorScheme.fromSwatch ,不过这个的灵活适配程度不如 fromSeed,所以使用 fromSeed 是比较好的选择。

因为 M3 默认从蓝色系列变成紫色系统,所以如果你用的是默认色系,那就更需要配置来恢复,本篇的目的就是,让 App 在 M3 下恢复到 M2 的 UI 效果,因为它真的不是仅仅一个颜色变化而已。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

如果你以前的 ThemeData 是如下所示代码,那么运行之后你会看到,原本应该是 M2 效果的正常列表,现在变成了 M3 那种「无法言喻」的效果,可以看到此时 M3 下 primarySwatch 其实并没有起到作用。

ThemeData(
  primarySwatch: Colors.blue,
  
)
  
M2 M3
Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

那么首先我们要做的就是增加 colorScheme ,但是你在加完会发现并没有什么变化,这是因为此时控件还是处于 M3 的色系下,所以接下来我们要首先全局恢复 Appbar

ThemeData(
  primarySwatch: Colors.blue,
  colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),

Do it。

AppBar

如下代码所示,我们先添加 AppBarTheme ,可以看到 AppBar 的背景这样就变回了蓝色,但是这时候 Appbar 的文本和图标还是黑色。

ThemeData(
  primarySwatch: Colors.blue,
  colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),

  appBarTheme: AppBarTheme(
    backgroundColor: Colors.blue,
  ),
),
Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

为了让图标和文本恢复到 M2 的白色,我们可以在 AppBarTheme 里配置 iconThemetitleTextStyle ,可以看到配置后如下图所示,UI 上 AppBar 已经恢复到 M2 的效果,那么此时你可以会疑惑,为什么修改的配置是 size: 24.0Typography.dense2021.titleLarge

AppBarTheme(
  iconTheme: IconThemeData(
    color: Colors.white,
    size: 24.0,
  ),
  backgroundColor: Colors.blue,
  titleTextStyle:  Typography.dense2014.titleLarge,
)

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

其实这就是本篇的核心:在 M2 控件还没被剔除的时候,通过参考源码将 M3 UI 恢复到 M2

例如在 3.16 的源码里,theme.useMaterial3 ? 这样的代码目前随处可见,而此时 AppBar 里:

  • _AppBarDefaultsM3 下 icon 的颜色是通过 onSurface 字段,大小是 24
  • _AppBarDefaultsM2 下 icon 是直接使用 theme 下默认的样式,也就是 size 24, 颜色白色。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

M2 M3
Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutterFlutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

所以我们可以在上面的 IconThemeData 里可以直接配置 color: Colors.white, size: 24.0, 来恢复到 M2 的效果。

当然你也可以配置 ColorSchemeonSurface 来改变颜色,但是这个影响返回太大,还是推荐配置 AppBarThemeIconThemeData

另外可以看到,此时还有一个 Typography.dense2014.titleLarge ,这又是哪里来的?还是回到_AppBarDefaultsM3 里,在 M3 下, AppBar 使用的是 ThemeData 下的 textTheme.titleLarge ,而默认字体样式配置,基本来自 Typography 对象。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Typography 里默认配置了大量字体配置,例如 Typography.dense2014 对应就是如下所示配置,从上面代码可以看到默认情况下 M2 用的是 Typography.material2014 ,对应就是 Typography.dense2014,也就是在 AppBar 上 Typography.dense2014.titleLarge 就可以让 M3 的 AppBar 文本恢复到 M2 的样式。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

看到这里你是否已经学会了大概的思路?

通过 theme.useMaterial3 去检索控件,然后在源码里找到 M2 的实现,然后将其修改到全局的主题设置里,比如 AppBar 的就通过 AppBarTheme 配置,如果是 M2 的实现又引用了某些默认配置,就去检索这些默认配置的起源,所以说 M3 这个坑是一个体力活。

当然,这个思路下,有一些控件适配起来还是会有坑,因为它的变化确实有点大,例如 Card 控件。

Card

如图所示,这是 Card 控件在 M2 和 M3 下的变化,除了默认弧度之后,最主要就是颜色发生了改变,从默认白色变成了带着浅蓝色的效果,但是这里有个坑,就是,此时就算你给 Card 设置 color: Colors.white, ,它也依旧会带着这个浅蓝色的效果

M2 M3
Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

那么这个颜色如何去除?其实只要 ColorScheme 下设置 surfaceTint 为透明色就可以了,如下图所示,因为 Card 的效果是通过封装 Material 控件实现,而 Material 在 M3 下会通过 elevationsurfaceTint 去合成一个覆盖色。

ColorScheme.fromSeed(
  seedColor: Colors.blue,

  ///影响 card 的表色,因为 M3 下是  applySurfaceTint ,在 Material 里
  surfaceTint: Colors.transparent,
),

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

所以根据判断,surfaceTint 设置成透明就可以去除 Card 这个覆盖色,这个逻辑在 BottomAppBar 里同样存在,所以如果你需要把它们都恢复都 M2 效果,那么就只需要把 surfaceTint 设置成透明色即可。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

所以类似的变动才是 M3 里最坑的点,如果你不了解他们的底层实现,那么在升级之后,发现明明代码给了白色,为什么它还是会有浅蓝色效果?这对于开发者来就是一个找🐛的天坑,所以在这里也用 Card 提供一个解决问题的典型思路。

另外还有一个典型的控件,那就是 FloatingActionButton(FAB) 。

FloatingActionButton

从 M2 到 M3, FloatingActionButton(FAB) 控件最大的变化就是变成了方形,其次颜色也不跟随之前和主题蓝色,我们不说 M3 这个「优化」如何,就说如何恢复到 M2 的效果。

M2 M3
Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

首先按照惯例,肯定有一个叫 floatingActionButtonTheme 的参数,可以用于配置 FloatingActionButtonThemeData ,所以这里我们首先添加上配置,然后通过 shape 先变回原形,并且修改 backgroundColor 变成蓝色。

floatingActionButtonTheme: FloatingActionButtonThemeData(
    backgroundColor: Colors.blue,
    shape: CircleBorder()
),

那么此时剩下的就是 Icon 的颜色,我们当然可以在用到 Icon 的地方手动修改为白色,但是我们希望的是全局配置默认恢复到 M2 时代,所以我们就要去找 FAB 下 Icon 是如何获取到颜色的。

而寻找这个颜色的实现,居然就让我开启了一段漫长的旅程·····

首先 Icon 肯定是通过 IconThemeData 去获取默认颜色,因为 FAB 的主题下没有 iconTheme 可以配置,那么首先就想到配置一个全局的 iconTheme: IconThemeData ,但是神奇的问题来了,配置之后居然无效。

那么就开始往上查找,然后依次返现, FAB 内部是通过 RawMaterialButton 实现的点击,而 RawMaterialButton 内部就有一个 IconTheme.merge 的实现,那么 FAB 里的 Icon 默认应该是使用了 effectiveTextColor 这个颜色

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

之后开始经历一番漫长检索关联,最终可以看到:

  • 这个 effectiveTextColor 来自从 FAB 传入的 TextSytle 的 color
  • textSytle 来自 extendedTextStyle
  • extendedTextStyle 来自 foregroundColor
  • foregroundColor 默认来自 floatingActionButtonThemeforegroundColor

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

所以破案了,需要全局设置 FAB 下 Icon 的颜色,是要配置 FloatingActionButtonThemeDataforegroundColor ,这个设定和名称正常情况下谁能想得到呢?

而且这个传递嵌套如此“隐晦”,只能说, FAB 是 Flutter 样式跟踪里很典型的一个代表:传递深,theme 引用复杂,类似 merge/copy 的局部实现太过隐蔽

floatingActionButtonTheme: FloatingActionButtonThemeData(
    backgroundColor: Colors.blue,
    foregroundColor:  Colors.blue,
    shape: CircleBorder()),

另外关于 IconThemeData 还有一个冷知识,参数不全的情况下,也就是不满足 isConcrete 的情况下,其他的参数在 of(context) 的时候是会被 fallback 覆盖,这个对于 M3 - M2 的降级适配里也是一个关键信息。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

primarySwatch

最后在聊一个 ThemeDataprimarySwatch,为什么聊它,因为如果你的代码里用了 primaryColorDarkprimaryColorLight 作为配置,那么使用 ColorScheme.fromSeed 之后,它们会发生一些「奇妙的变化」,所以为了它们可以恢复到 M2 模式,那么设置 primarySwatch 可以将它们恢复到原有的效果。

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧,flutter

最后

如下所示是本次升级适配里的示例代码总和,其实 M3 模式下「降级」到 M2 UI 效果真的是一个体力活,类似上面三个典型的例子,都可以看出来跟踪默认 UI 的实现并不轻松,虽然对于 Flutter 团队来说,升级到 M3 可能是一次正向优化,但是对于不喜欢 Material Design 的国区而言,M3 只能是一个负优化,不知道大家同意不?文章来源地址https://www.toymoban.com/news/detail-754087.html

return ThemeData(
  ///用来适配 Theme.of(context).primaryColorLight 和 primaryColorDark 的颜色变化,不设置可能会是默认蓝色
  primarySwatch: color as MaterialColor,

  /// Card 在 M3 下,会有 apply Overlay

  colorScheme: ColorScheme.fromSeed(
    seedColor: color,
    primary: color,

    brightness: Brightness.light,

    ///影响 card 的表色,因为 M3 下是  applySurfaceTint ,在 Material 里
    surfaceTint: Colors.transparent,
  ),

  /// 受到 iconThemeData.isConcrete 的印象,需要全参数才不会进入 fallback
  iconTheme: IconThemeData(
    size: 24.0,
    fill: 0.0,
    weight: 400.0,
    grade: 0.0,
    opticalSize: 48.0,
    color: Colors.white,
    opacity: 0.8,
  ),

  ///修改 FloatingActionButton的默认主题行为
  floatingActionButtonTheme: FloatingActionButtonThemeData(
      foregroundColor: Colors.white,
      backgroundColor: color,
      shape: CircleBorder()),
  appBarTheme: AppBarTheme(
    iconTheme: IconThemeData(
      color: Colors.white,
      size: 24.0,
    ),
    backgroundColor: color,
    titleTextStyle: Typography.dense2014.titleLarge,
    systemOverlayStyle: SystemUiOverlayStyle.light,
  ),

到了这里,关于Flutter 小技巧之 3.16 升级最坑 M3 默认适配技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • flutter-移动端适配

    不同屏幕之间的尺寸适配 使用插件 flutter_screenutil flutter 屏幕适配方案,用于调整屏幕和字体大小的flutter插件,让你的UI在不同尺寸的屏幕上都能显示合理的布局! 安装 # add flutter_screenutil flutter_screenutil: ^5.8.4

    2024年02月12日
    浏览(31)
  • Flutter:屏幕适配

    flutter_screenutil 是一个用于在Flutter应用程序中进行屏幕适配的工具包。它旨在帮助开发者在不同屏幕尺寸和密度的设备上创建响应式的UI布局。 `flutter_screenutil``提供了一些用于处理尺寸和间距的方法,使得开发者可以根据设备的屏幕尺寸和密度来动态调整UI元素的大小和位置。

    2024年02月13日
    浏览(42)
  • 【Flutter】Flutter 设置默认字体 设置自定义字体

    你是否渴望成为 Flutter 的专家,掌握更多的技巧和最佳实践?我们有个好消息要告诉你! Flutter 从零到一 基础入门到应用上线全攻略 正在等待你的加入!这个专栏包含了你需要的所有 Flutter 学习资源

    2024年02月09日
    浏览(54)
  • Flutter屏幕适配的三种方案

    做移动端开发的同学都知道,针对不同型号和尺寸的手机要进行页面的适配,且 iOS 和 Android 适配方案各不相同,那我们用 Flutter 开发要怎么处理屏幕适配呢? Flutter使用的是类似于iOS中的点pt,也就是point。我们经常说 iPhone8 的尺寸是375x667,但是它的分辨率其实是 750x1334 。因

    2024年02月06日
    浏览(35)
  • flutter2.1升级flutter3.0

    下载最新fluttert版本 for github 升级kotlin版本 及 gradle版本 Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15. Failed to apply plugin ‘kotlin-android’. [ +4 ms] The current Gradle version 6.7 is not compatible with the Kotlin Gradle plugin. Please use Gradle 6

    2023年04月09日
    浏览(36)
  • Flutter层对于Android 13存储权限的适配问题

    感觉很久没有写博客了,不对,的确是很久没有写博客了。原因我不怎么想说,玩物丧志了。后面渐渐要恢复之前的写作节奏。今天来聊聊我最近遇到的一个问题: Android 13版本对于storage权限的控制问题。 我们都知道,Android的每个版本更新都会伴随着搞事,也就是所谓的谷

    2024年02月07日
    浏览(39)
  • flutter升级、降级操作步骤

    打开运行终端 直接输入 flutter upgrade 版本号 需要先确定想要降级的版本号。 切换到系统安装flutter的目录 在https://github.com/flutter/flutter,找到要回退的版本号对应的commit序号(具体查找方法如图) 终端执行git reset —hard commitId 再执行flutter doctor 此时就已经降级成功了 可以执行

    2024年02月02日
    浏览(54)
  • 强大的Flutter App升级功能

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 应用程序升级功能是App的基础功能之一,如果没有此功能会造成用户无法升级,应用程序的bug或者新功能老用户无法触达,甚至损失这部分用户。 对于应用程序升级功能的重要性就无需赘

    2024年04月15日
    浏览(41)
  • flutter开发实战-颜色Color与16进制转换

    flutter开发实战-颜色Color与16进制转换 代码如下 https://blog.csdn.net/gloryFlow/article/details/132219192 flutter开发实战-颜色Color与16进制转换。 学习记录,每天不停进步。

    2024年02月13日
    浏览(40)
  • 轻松掌握Flutter中的键盘操作技巧

    嗨!这里是 甜瓜看代码 ,我们来聊聊如何避免你的用户在键盘弹起时受到惊吓。   我们都知道,在Flutter中,可以通过TextField或TextFormField来实现文本输入框。但是,这些输入框与键盘之间的交互可能会导致一些棘手的问题,例如键盘覆盖输入框、滚动问题等等。下面是一

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包