Flutter使用marquee包出现hasSize错误 包裹Expanded仍无法解决
问题详情
目标
可以正常使用Marquee()组件,不触发报错。
已执行操作
- 安装了marquee包
- 编写代码如下:
import 'package:marquee/marquee.dart'; // 在Column()中 Marquee( text: "Exampleeeeeeeeeeeeeeeeeee", pauseAfterRound: const Duration(seconds: 1), style: const TextStyle(fontSize: 20), ),
报错情况
调试控制台无报错,但dart文件中出现高亮错误代码:
// errors_patch.dart static _doThrowNew(int assertionStart, int assertionEnd, Object? message) native "AssertionError_throwNew";
已尝试的解决方案
查询到使用Expanded包裹可解决该错误,按如下方式修改代码后错误仍存在:
Expanded( child: Marquee( text: "Exampleeeeeeeeeeeeeeeee", pauseAfterRound: const Duration(seconds: 1), style: const TextStyle(fontSize: 20), )),
报错日志如下:
════════ Exception caught by rendering library ═════════════════════════════════ RenderBox was not laid out: RenderViewport#96fb3 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE 'package:flutter/src/rendering/box.dart': package:flutter/…/rendering/box.dart:1 Failed assertion: line 1999 pos 12: 'hasSize' The relevant error-causing widget was Marquee lib\favorites.dart:167 ════════════════════════════════════════════════════════════════════════════════
开发环境
执行flutter doctor -v结果如下:
[√] Flutter (Channel beta, 2.6.0-5.2.pre, on Microsoft Windows [Version 10.0.22000.282], locale ja-JP) • Flutter version 2.6.0-5.2.pre at D:\src\flutter_windows_2.5.0-stable\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 400608f101 (6周前), 2021-09-15 15:50:26 -0700 • Engine revision 1d521d89d8 • Dart version 2.15.0 (build 2.15.0-82.2.beta) [√] Android toolchain - 安卓应用开发 (Android SDK version 29.0.3) • Android SDK 路径为 D:\Android • Platform android-30, build-tools 29.0.3 • Java 二进制文件路径为: D:\Program Files\Android\Android Studio\jre\bin\java • Java 版本 OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174) • 所有安卓许可均已接受 [√] Chrome - Web端开发 • Chrome 路径为 C:\Program Files\Google\Chrome\Application\chrome.exe [√] Android Studio (version 4.2) • Android Studio 路径为 D:\Program Files\Android\Android Studio • Flutter 与 Dart 插件均已正常安装 • Java 版本 OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174) [√] VS Code (version 1.61.2) • VS Code 路径为 C:\Users\yukik\AppData\Local\Programs\Microsoft VS Code • Flutter 插件版本 3.27.0 [√] 已连接3个可用设备 • Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (模拟器) • Chrome (web) • chrome • web-javascript • Google Chrome 95.0.4638.54 • Edge (web) • edge • web-javascript • Microsoft Edge 95.0.1020.40 • 未发现任何问题!
解决方案
错误根因
该hasSize报错本质是Marquee组件无法获取到有效的布局约束:Marquee依赖父组件传递的确定宽高才能完成渲染,放置在Column中时,Column的主轴方向是垂直无边界的,直接放置Marquee会无法确定高度;即使用Expanded包裹,如果外层Column本身也处于无高度边界的容器(比如SingleChildScrollView、ListView)内,Expanded也无法计算得到可用高度,就会触发该报错。
可行修复方案
方案1:指定Marquee固定高度(通用适配方案)
无需Expanded包裹,直接用SizedBox给Marquee设置匹配字号的固定高度即可,示例代码如下:
// 在Column()中 SizedBox( height: 28, // 字号为20时,高度设置在25-30区间即可 child: Marquee( text: "Exampleeeeeeeeeeeeeeeeeee", pauseAfterRound: const Duration(seconds: 1), style: const TextStyle(fontSize: 20), ), )
方案2:确保Expanded父容器有确定高度
如果需要Marquee占用Column的剩余空间,需确认Column的父容器有明确的高度限制(比如父容器为页面根容器,可适配屏幕完整高度),此时Expanded可正常计算可用高度,示例代码如下:
Column( children: [ // 其他自定义组件 Expanded( child: Marquee( text: "Exampleeeeeeeeeeeeeeeeeee", pauseAfterRound: const Duration(seconds: 1), style: const TextStyle(fontSize: 20), ), ), // 其他自定义组件 ], )
兼容性排查
当前使用的是Flutter 2.6 beta版本,存在框架兼容性风险,如上述方案未解决问题,可尝试以下操作:
- 将marquee包升级到最新正式版本
- 切换到Flutter稳定版分支重新编译测试
内容的提问来源于stack exchange,提问作者Beginner_
相关产品推荐
相关产品推荐

