Flutter中build方法如何更新Row内的Text并解决const列表报错问题
错误原因
你遇到的编译错误完全是你主动给Row的children参数加了const修饰符导致的:
const列表要求列表内的所有元素都必须是编译期就能确定的常量- 你创建的
displayText用了两个运行时才能拿到的值:一个是timerDisplay()计算出的实时时间,另一个是父组件传入的widget.timerStyle,这两个值编译期都无法确定,所以这个Text不可能是const类型 - 你代码里的
const <Widget>[]是你主动加的编译期优化标记,不是Flutter要求必须加的,当列表包含动态生成的组件时,就不能加这个const修饰。
修正后的完整实现
如果要实现实时更新的计时器功能,还需要加周期性触发器调用setState触发重绘,完整代码如下:
import 'package:flutter/material.dart'; import 'dart:async'; class GameTimer extends StatefulWidget { final TextStyle timerStyle; const GameTimer({Key? key, required this.timerStyle}) : super(key: key); @override State createState() => _TimerState(); } class _TimerState extends State<GameTimer> { final startedAt = DateTime.now(); late Timer _timer; @override void initState() { super.initState(); // 每秒触发一次重绘更新时间 _timer = Timer.periodic(const Duration(seconds: 1), (timer) { setState(() {}); }); } String timerDisplay() { int minutes = (DateTime.now().difference(startedAt).inSeconds / 60).floor(); return '$minutes'; } @override Widget build(BuildContext context) { var displayText = Text(timerDisplay(), style: widget.timerStyle); return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, // 移除const修饰符 children: <Widget>[ const Icon(Icons.play_circle), // 这个Icon是常量,可以单独加const优化 displayText, ]); } @override void dispose() { // 销毁定时器避免内存泄漏 _timer.cancel(); super.dispose(); } }
动态更新逻辑说明
你之前对Flutter更新机制的理解是对的:界面更新靠build重建组件实现,不需要修改旧组件。只要你调用setState触发当前State的build方法重执行,build方法里会用最新的状态生成新的Text组件,Flutter会自动对比新旧Widget树的差异,更新对应渲染节点的内容。
如果你不需要实时自动刷新,只需要在特定事件触发时更新时间,只需要在对应的事件回调里调用setState即可,不需要加周期性定时器。
内容的提问来源于stack exchange,提问作者Marvin
相关产品推荐
相关产品推荐

