Flutter开发:用户输入仅热重载显示 提交按钮无响应问题
问题根因
代码存在3个核心问题,导致点击提交按钮后待办区不更新,仅热重载后才显示内容:
- 状态作用域错误:
_textController、userInput、toDoList全部定义为全局变量,点击按钮时仅调用了LandingPage组件的setState,该方法只会触发LandingPage自身的重绘,独立的ToDos组件不会收到刷新通知,只有热重载触发全量应用刷新时才会读取到更新后的变量值。 - 子组件被常量修饰:代码中写的
const ToDos()是编译期常量,创建后不会响应任何状态变化。 - 渲染逻辑错误:两个dart文件存在循环导入问题;
ToDos组件没有遍历待办列表渲染,仅固定展示单个全局userInput值,无法支持多条待办展示;TextEditingController没有做资源释放,长期运行会触发内存泄漏。
修复步骤
- 收拢状态到父组件:把输入控制器、待办列表全部移到
_LandingPageState内部管理,删除所有零散的全局变量,删除to_do_section.dart中对landing_page.dart的导入,解决循环引用问题。 - 改造子组件传参:给
ToDos组件新增必传的待办列表参数,移除ToDos实例前的const修饰符,父组件更新列表后自动触发子组件重绘。 - 补全交互逻辑:提交时增加空内容判断,提交成功后清空输入框;在父组件
dispose生命周期中释放输入控制器;子组件中用列表组件遍历传入的待办数据做渲染。
修正后代码
landing_page.dart
import 'package:flutter/material.dart'; import 'package:flutter_application_1/presentation/widgets/to_do_section.dart'; import 'package:flutter_application_1/responsive_layout.dart'; class LandingPage extends StatefulWidget { const LandingPage({Key? key}) : super(key: key); @override State<LandingPage> createState() => _LandingPageState(); } class _LandingPageState extends State<LandingPage> { // 状态统一放在父组件管理 final _textController = TextEditingController(); final List<String> toDoList = []; @override void dispose() { // 销毁控制器避免内存泄漏 _textController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Center(child: Text("To-Do-App")), backgroundColor: Colors.redAccent, ), body: SingleChildScrollView( child: Column( children: [ // 移除const,向子组件传递待办列表 ToDos(todoList: toDoList), _buildToDoAddArea() ], ), ), ); } Column _buildToDoAddArea() { return Column( children: [ Padding( padding: const EdgeInsets.only(top: 8.0, left: 20, right: 20, bottom: 20), child: TextField( controller: _textController, textAlign: TextAlign.center, decoration: const InputDecoration( border: OutlineInputBorder(), hintText: "Add a new ToDo", ), ), ), MaterialButton( color: Colors.redAccent, onPressed: () { final inputContent = _textController.text.trim(); // 空输入不添加 if (inputContent.isEmpty) return; setState(() { toDoList.add(inputContent); }); // 提交后清空输入框 _textController.clear(); }, child: const Text("Add", style: TextStyle(color: Colors.white)), ), ], ); } }
to_do_section.dart
import 'package:flutter/material.dart'; import 'package:flutter_application_1/responsive_layout.dart'; class ToDos extends StatefulWidget { // 接收父组件传入的待办列表 final List<String> todoList; const ToDos({Key? key, required this.todoList}) : super(key: key); @override State<ToDos> createState() => _ToDosState(); } class _ToDosState extends State<ToDos> { @override Widget build(BuildContext context) { SizeConfig().init(context); return Padding( padding: EdgeInsets.only( top: SizeConfig.blockSizeHorizontal * 10, left: SizeConfig.blockSizeVertical * 2.5, right: SizeConfig.blockSizeVertical * 2.5, bottom: SizeConfig.screenHeight / 8 ), child: SizedBox( width: SizeConfig.blockSizeHorizontal*100, height: SizeConfig.blockSizeVertical*40, child: Container( decoration: BoxDecoration( color: Colors.grey[400], borderRadius: BorderRadius.circular(30), border: Border.all( color: Colors.black45, style: BorderStyle.solid, width: 4)), child: Padding( padding: const EdgeInsets.all(8.0), // 遍历传入的待办列表渲染 child: ListView.builder( itemCount: widget.todoList.length, itemBuilder: (context, index) { return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Text(widget.todoList[index]), ), ); }, ) ), ), ), ); } }
内容的提问来源于stack exchange,提问作者laniakea
相关产品推荐
相关产品推荐

