Flutter中点击按钮新增带图片和输入框的Container组件如何实现?
实现方案
核心逻辑:将每个表单对应的控制器和数据独立封装,用列表维护所有表单实例,点击新增按钮时往列表追加新的表单实例,触发页面刷新即可完成新增。
步骤1:定义表单数据模型
用来独立存储每个表单的输入控制器和后续可能用到的图片数据,避免多个表单输入内容冲突
// 每个产品表单对应的数据模型 class ProductFormData { // 两个输入框对应的独立控制器 late TextEditingController controller1; late TextEditingController controller2; // 如果需要存储两张上传的图片数据,可在这里补充对应字段,比如 // String? productImgPath1; // String? productImgPath2; ProductFormData() { controller1 = TextEditingController(); controller2 = TextEditingController(); } // 释放控制器避免内存泄漏 void dispose() { controller1.dispose(); controller2.dispose(); } }
步骤2:在页面State中声明表单维护列表
class _YourPageState extends State<YourPage> { // 存储所有产品表单数据,默认初始化1个,对应页面首次加载显示的表单 List<ProductFormData> productFormList = [ProductFormData()]; // 重写dispose方法,页面销毁时释放所有表单的控制器 @override void dispose() { for (var form in productFormList) { form.dispose(); } super.dispose(); }
步骤3:改造原有_productForm方法
接收表单数据作为参数,使用对应表单自己的控制器
// 传入表单数据生成对应的Container组件 Container _productForm(ProductFormData formData) { return Container( margin: const EdgeInsets.only(bottom: 20), // 多个表单之间保留间距 child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _productImage(), // 如果要存储图片,可把formData传进去赋值 _productImage(), ], ), _heightPadding(15), _inputText("input text", formData.controller1), _heightPadding(15), _inputText("input text", formData.controller2), ], ), ); }
步骤4:改造页面主布局
遍历表单列表生成所有表单,加滚动组件避免表单数量过多时页面溢出
@override Widget build(BuildContext context) { return Scaffold( body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( children: [ // 遍历生成所有已添加的表单 ...productFormList.map((form) => _productForm(form)).toList(), // 底部放新增按钮 _addButton(), ], ), ), ); }
步骤5:给新增按钮添加点击逻辑
Widget _addButton() { return Container( width: 200, height: 65, child: ElevatedButton( onPressed: () { // 往列表追加新的表单实例,setState触发页面刷新 setState(() { productFormList.add(ProductFormData()); }); }, child: const Text( 'Add Container', style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold), ), style: ElevatedButton.styleFrom( primary: Colors.blue, onPrimary: Colors.white, ), ), ); }
补充说明
如果后续需要获取所有表单的输入内容,直接遍历productFormList,取每个元素的controller1.text、controller2.text即可;如果需要支持删除表单,只需要给每个表单加删除按钮,点击时删除列表对应索引的元素后调用setState即可。
内容的提问来源于stack exchange,提问作者Kevin Yang
相关产品推荐
相关产品推荐

