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解决不了的问题。如果不能,请升级套餐。 _

相关推荐
2501_9160088920 分钟前
如何实现iOS App代码混淆:SwiftShield使用指南
android·ios·小程序·https·uni-app·iphone·webview
2501_9159090636 分钟前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
恋猫de小郭1 小时前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
zihan5181 小时前
自己做软件日记9/21 得到了一个良好的文件结构框架
后端·flutter·前端框架·android studio
AFinalStone1 小时前
Android7 SystemUI 源码解析(六)QuickSettings快捷设置面板
android·systemui
Kapaseker1 小时前
你有搞明白 Volatile 什么意思吗?
android·kotlin
美狐美颜SDK开放平台1 小时前
直播APP源码与视频美颜sdk如何配合?一套完整开发思路
android·人工智能·计算机视觉·音视频·直播美颜sdk
心平气和量大福大2 小时前
android-权限
android·java
2501_916008892 小时前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
智慧物业老杨4 小时前
物业日常巡查的数智化重构:从“打卡式巡检“到“闭环式风控“
android·java·人工智能·系统架构·rxjava