如何在Flutter中从一个Stateful Widget更新另一个Stateful Widget?
解决方案:使用Flutter状态提升(State Lifting)
不用全局变量或第三方状态管理库,最符合Flutter标准特性的方案是状态提升——把共享状态放到组件树中最近的共同父组件里,通过回调函数传递状态更新,再将状态向下传递给需要的子组件。
以下是修改后的完整代码:
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Circuit Cellar!', theme: ThemeData(primarySwatch: Colors.blue), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { // 共享状态移至父组件State中 final List<String> taskLabels = [ 'Embedded in Thin Slices', 'Technology Features', 'Datasheets', ]; int _selectedTaskCount = 0; // 计算进度百分比 double get _progressPercentage => _selectedTaskCount / taskLabels.length; // 子组件Checkbox点击回调 void _onTaskToggled(bool isSelected) { setState(() { if (isSelected) { _selectedTaskCount++; } else { _selectedTaskCount--; } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Circuit Cellar Reading Planner!'), ), body: Column( children: [ // 向Progress组件传递进度值 Progress(percent: _progressPercentage), // 向TaskList传递任务列表和回调 TaskList( taskLabels: taskLabels, onTaskToggled: _onTaskToggled, ), ], ), ); } } class Progress extends StatelessWidget { final double percent; // 接收父组件传递的进度值 const Progress({super.key, required this.percent}); @override Widget build(BuildContext context) { return Column( children: [ const Text('Reading Progress:'), LinearProgressIndicator(value: percent), ], ); } } class TaskList extends StatelessWidget { final List<String> taskLabels; final Function(bool) onTaskToggled; const TaskList({ super.key, required this.taskLabels, required this.onTaskToggled, }); @override Widget build(BuildContext context) { return Column( children: taskLabels .map((label) => TaskItem( label: label, onToggle: onTaskToggled, )) .toList(), ); } } class TaskItem extends StatefulWidget { final String label; final Function(bool) onToggle; const TaskItem({ super.key, required this.label, required this.onToggle, }); @override State<TaskItem> createState() => _TaskItemState(); } class _TaskItemState extends State<TaskItem> { bool _isChecked = false; @override Widget build(BuildContext context) { return Row( children: [ Checkbox( onChanged: (newValue) { setState(() { _isChecked = newValue ?? false; // 调用父组件回调,通知状态更新 widget.onToggle(_isChecked); }); }, value: _isChecked, ), Text(widget.label), ], ); } }
关键改动说明:
- 状态集中管理:把选中任务数量、任务标签列表移到
_MyHomePageState中,消除全局变量,让状态在可控范围内流转。 - 组件职责拆分:
Progress改为无状态组件,直接接收父组件传递的进度值完成渲染。TaskList负责生成任务项,将父组件的回调传递给每个TaskItem。TaskItem仅维护自身选中状态,点击时通过回调通知父组件更新全局计数。
- 回调传递状态:通过
onTaskToggled回调将子组件的交互事件传递给父组件,触发父组件setState,自动更新所有依赖该状态的子组件(包括Progress)。 - 修正原代码错误:修复了原代码中
TasbkItem的拼写错误,统一为TaskItem。
内容的提问来源于stack exchange,提问作者rjapenga
相关产品推荐
相关产品推荐

