flutter 展示的字体突然奔放了

开始的时候好好的

突然就奔放起来了

没想到,没想到啊

一、现象

界面突然风格变了。

字体变大了,而且没有指定颜色的,用了大红色。 Text都有黄色的双下划线。

这个代码没有改动的。正常情况应该是:

这是想要的效果。

二、结论

makefile 复制代码
flutter_easyloading: ^4.0.2

升级后导致问题。上一个版本3.0.5是2022.05.23 发布的,终于发布4.X版本,更新日志没有说会影响到啥。没想到对于showCupertinoModalPopup()竟然会有样式的影响。

解决方法

EasyLoading初始化的时候,修改为:

css 复制代码
builder: EasyLoading.init(
  builder: (context, child) {
    return DefaultTextStyle(style: Theme.of(context).textTheme.bodyMedium!, child: child!);
  },
)

找了很久没有找到原因,还是AI帮我找到的。以后我应该是测试人员,而不是开发人员了。

三、原因

EasyLoading的初始化是一样的。

less 复制代码
MaterialApp(
    initialRoute: "/",
    builder: EasyLoading.init(),
)

1. 旧版本

EasyLoading在3.0.5版本中:

kotlin 复制代码
@override
  Widget build(BuildContext context) {
    return Material(
      child: Overlay(
        initialEntries: [
          EasyLoadingOverlayEntry(
            builder: (BuildContext context) {
              if (widget.child != null) {
                return widget.child!;
              } else {
                return Container();
              }
            },
          ),
          _overlayEntry,
        ],
      ),
    );
  }

这个 Material 会给下面的根 Navigator/Overlay 提供正常的 Material 默认文字样式。

所以在使用 showCupertinoModalPopup的时候用到了EasyLoading设置的Material

2. 新版本

EasyLoading在4.X版本中:

less 复制代码
@override
  Widget build(BuildContext context) {
    _syncOverlay();
    final session = easyLoadingRuntime.session;
    return Stack(
      fit: StackFit.passthrough,
      clipBehavior: Clip.none,
      children: <Widget>[
        Material(
          type: MaterialType.transparency,
          textStyle: DefaultTextStyle.of(context).style,
          child: widget.child ?? const SizedBox.shrink(),
        ),
        if (session != null)
          Positioned.fill(
            child: _EasyLoadingOverlay(
              key: _overlayKey,
              session: session,
              onPresented: () => easyLoadingRuntime.didPresent(session.id),
              onDismiss: () {
                unawaited(
                  easyLoadingRuntime.dismiss(
                    reason: EasyLoadingDismissReason.tap,
                  ),
                );
              },
            ),
          ),
      ],
    );
  }
}

设置的textStyleDefaultTextStyle.of(context).style, 也就是MaterialApp中的样式。

SO showCupertinoModalPopup使用到了EasyLoading设置的Material

3. 原因

执行了showCupertinoModalPopup后的图层结构为:

sql 复制代码
MaterialApp
└─ EasyLoading 包装层
   └─ 根 Navigator
      └─ Overlay
         ├─ 原页面 Route
         │  └─ Scaffold
         │     └─ 正常 Material 文字环境
         │
         └─ CupertinoModalPopupRoute
            └─ CouponPackageDetail

CouponPackageDetail 为弹窗中的视图,它没有设置Material。SO 继承了根Navigator上面的EasyLoading包装层的Material

旧版本

没有指定textStyle,所以使用了默认的Theme.of(context).textTheme.bodyMedium.

新版本

指定textStyleDefaultTextStyle.of(context).style,此DefaultTextStyle获取到的是MaterialApp中的textStyle:

php 复制代码
Widget _buildWidgetApp(BuildContext context) {
    final Color materialColor = widget.color ?? widget.theme?.primaryColor ?? Colors.blue;
    if (_usesRouter) {
      return WidgetsApp.router(
        key: GlobalObjectKey(this),
        routeInformationProvider: widget.routeInformationProvider,
        routeInformationParser: widget.routeInformationParser,
        routerDelegate: widget.routerDelegate,
        routerConfig: widget.routerConfig,
        backButtonDispatcher: widget.backButtonDispatcher,
        onNavigationNotification: widget.onNavigationNotification,
        builder: _materialBuilder,
        title: widget.title,
        onGenerateTitle: widget.onGenerateTitle,
        textStyle: _errorTextStyle,
        color: materialColor,
        locale: widget.locale,
        localizationsDelegates: _localizationsDelegates,
        localeResolutionCallback: widget.localeResolutionCallback,
        localeListResolutionCallback: widget.localeListResolutionCallback,
        supportedLocales: widget.supportedLocales,
        showPerformanceOverlay: widget.showPerformanceOverlay,
        showSemanticsDebugger: widget.showSemanticsDebugger,
        debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner,
        exitWidgetSelectionButtonBuilder: _exitWidgetSelectionButtonBuilder,
        moveExitWidgetSelectionButtonBuilder: _moveExitWidgetSelectionButtonBuilder,
        tapBehaviorButtonBuilder: _tapBehaviorButtonBuilder,
        shortcuts: widget.shortcuts,
        actions: widget.actions,
        restorationScopeId: widget.restorationScopeId,
      );
    }

_MaterialAppStatebuild设置为_errorTextStyle:

less 复制代码
const TextStyle _errorTextStyle = TextStyle(
  color: Color(0xD0FF0000),
  fontFamily: 'monospace',
  fontSize: 48.0,
  fontWeight: FontWeight.w900,
  decoration: TextDecoration.underline,
  decorationColor: Color(0xFFFFFF00),
  decorationStyle: TextDecorationStyle.double,
  debugLabel: 'fallback style; consider putting your text in a Material',
);

对,就是它,看到的就是它。

如果弹窗等``

四、 Overlay

Overlay 是 Flutter 中专门用来"叠加显示 UI"的一个容器。它允许新的 Widget 覆盖在当前页面上面,而不需要替换当前页面。

Navigator中的Overlay有很多Route:

css 复制代码
Navigator
└─ Overlay
   ├─ Route A
   ├─ Route B
   ├─ Dialog Route
   ├─ Popup Route
   └─ 其他浮层

在执行showCupertinoModalPopup的时候:

sql 复制代码
MaterialApp
│
└─ EasyLoading
   │
   └─ Navigator
      │
      └─ Overlay
         │
         ├─ 原页面 Route
         │  └─ Scaffold
         │     └─ 页面内容
         │
         ├─ ModalBarrier
         │  └─ 半透明遮罩
         │
         └─ CupertinoModalPopupRoute
            └─ CouponPackageDetail

CouponPackageDetail不是弹窗所在的页面的child,而是创建了一个route: CupertinoModalPopupRoute, 所以不会继承原页面的Material

完结

AI时代,没有AI解决不了的问题。如果不能,请升级套餐。 _

相关推荐
FungLeo8 小时前
Flutter 吸顶分组列表实战:语义桶分组 + 点击头平滑滚动
android·flutter
阿巴斯甜9 小时前
Android 自定义权限
android
FungLeo9 小时前
Flutter 超长 StatefulWidget 拆分术:part of + extension on State 实战
android·flutter·dart
小王C语言11 小时前
MySQL 数据类型:数值类型、字符串类型、日期和时间类型、enum 和 set、find_in_set 查询
android·数据库·mysql
我命由我1234511 小时前
Android 控件 - CardView(快速实现圆角)
android·java·java-ee·kotlin·android studio·android-studio·android runtime
GitLqr11 小时前
Impeller 时代:Shader Jank 消失了,但渲染性能的战场也变了
flutter·面试·性能优化
码云数智-园园11 小时前
Android 全方位性能优化合集
android·性能优化
hunterandroid12 小时前
[Android 从零到一] Compose 动画实战:从 AnimatedVisibility 到复杂转场与手势联动
android
Knight_AL12 小时前
Lombok @Builder 踩坑:build() 前后对象类型不一样
android·java·开发语言
大黄说说13 小时前
Android 本地存储深度对比:SharedPreferences、MMKV、Room 数据库怎么选?
android·数据库