Flutter单页面如何使用多个image_picker实现各图片容器独立选图
问题根源
你遇到的两个问题核心原因有两点:
- 所有图片容器共用全局的
_pickedImage变量存储选中的图片,修改该变量会导致所有容器同步更新 - 直接将Widget存入列表渲染,没有通过数据驱动渲染,无法实现单个容器的数据独立绑定
具体实现方案
第一步:调整状态变量
把原来存Widget的列表换成存图片数据的列表,删除全局的单个_pickedImage变量:
// 每个元素对应一个容器的图片资源,初始为null代表未选图,兼容web/移动端不同存储类型 List<dynamic> _pickedImages = []; bool addImageSelete = false; bool isWeb = false; final picker = ImagePicker();
第二步:修改添加容器的按钮逻辑
点击添加按钮时,往图片数据列表加一个null元素即可,不需要提前生成Widget:
// 原_addButton()的点击事件修改为 void _addImageContainer() { setState(() { _pickedImages.add(null); }); }
第三步:重写ListView.builder渲染逻辑
直接根据数据列表的长度生成容器,把当前index传入容器组件:
Container( height: isWeb ? 300 : MediaQuery.of(context).size.width * 2 / 5, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Expanded( child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (context, index) { return _detailImage(index); // 把当前index传入组件 }, itemCount: _pickedImages.length, ), ), ], ), ), _addButton(),
第四步:修改图片容器组件,绑定对应index的数据
组件接收index参数,显示对应位置的图片,点击时将index传给选图方法:
Widget _detailImage(int index) { return InkWell( onTap: () async { await _seletedDialogBox(context); if (addImageSelete) { // 把当前index传入选图方法 _getImage(index, source: ImageSource.gallery); } setState(() { addImageSelete = false; }); }, child: Container( margin: EdgeInsets.symmetric(horizontal: 10), width: MediaQuery.of(context).size.width * 2 / 5, height: MediaQuery.of(context).size.width * 2 / 5, child: _pickedImages[index] == null ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: const [ Text("Not Image Yet"), ], ), ) : isWeb ? _pickedImages[index] : Image.file( _pickedImages[index], fit: BoxFit.cover, ), ), ); }
第五步:修改选图方法,根据index更新对应位置的图片
Future<void> _getImage(int index, {ImageSource source}) async { PickedFile imageTest = await picker.getImage(source: source); setState(() { if (imageTest != null) { if (isWeb) { _pickedImages[index] = Image.network( imageTest.path, fit: BoxFit.cover, ); } else { _pickedImages[index] = File(imageTest.path); } } }); }
内容的提问来源于stack exchange,提问作者Kevin Yang
相关产品推荐
相关产品推荐

