Flutter多图上传组件

Flutter多图上传组件

项目开发过程中,需要多图上传组件,但目前网络上没有完全符合需求的组件,故在参考的基础上自行编写了一个多图上传组件。

该组件依赖image_pickerdio

效果图
在这里插入图片描述

该组件目前仅支持一次上传一张图片,每次增加图片按钮会随之移动

代码:

List imgPathList;//存储图片地址
List imageId;//存储图片id
@override
  Widget build(BuildContext context) {
    return Container(
            padding: sInsetsHV(20, 0),
            width: double.infinity,
            child: Wrap(
              spacing: sWidth(10),
              runSpacing: sWidth(20),
              children: renderImgList(),
            )
        );
  }

 List<Widget> renderImgList(){
    List<Widget> widgetList = [];
    for (int index=0 ; index< this.imgPathList.length; index++){
      var image = renderImg(index);
      widgetList.add(image);
    }
    if(this.imgPathList.length<9){//限制最多9张,达到9张隐藏按钮
      widgetList.add(addImgButton());
    }
    return widgetList;
  }

  Widget renderImg(int index){
    return InkWell(
      child: Container(
          width: sWidth(160),
          height: sHeight(160),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(4.0),
          ),
          //隐藏id值,删除图片时可以直接获取到对应图片id
          child: Visibility(
            visible: false,
            replacement: Stack(
              children: [
                CustomCacheNetworkImage(
                  this.imgPathList[index],
                  fit: BoxFit.fill,
                  width: sWidth(160),
                  height: sHeight(160),
                ),
                Positioned(
                  top: 0,
                  right: 0,
                  child: CustomClickWidget(//自定义的点击组件,使用时替换成自己的
                    behavior: HitTestBehavior.opaque,
                    child: Container(
                      color: Color(0xFF000000).withOpacity(0.4),
                      width: sWidth(36),
                      height: sHeight(36),
                      child: Icon(Icons.close,color: Colors.white,size: ScreenUtil().setSp(28),),
                    ),
                    singleClick: (){
                      _deleteImg(index);
                    },
                  ),
                )
              ],
            ),
            child: Text('${this.imgIdList[index]}'),
          )
      ),
    );
  }

  Widget addImgButton(){//添加图片的按钮
    return InkWell(
      child: Container(
        width: sWidth(160),
        height: sHeight(160),
        margin: EdgeInsets.only(right: sWidth(20)),
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(4.0),
            border: Border.all(
              width: sWidth(2),
              color: Color(0xFFB3B3B3),
            )
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.add,size: ScreenUtil().setSp(60),color: Color(0xFFD8D8D8),),
            SizedBox(height: sHeight(10),),
            CommonText('上传图片',fontSize: 22,fontWeight: FontWeight.w500,textColor: Color(0xFF999999),)
          ],
        ),
      ),
      onTap: _openGallery,
    );
  }

  //选择相册照片&上传
  void _openGallery () async {
  //获取相册图片
    PickedFile image = await ImagePicker().getImage(source: ImageSource.gallery, maxHeight: sHeight(150), maxWidth:sWidth(150));
	//获取图片本地路径
    String path = image.path;
    //获取文件名
    String imgName = path.substring(path.lastIndexOf("/") + 1, path.length);
    //获取格式
    String suffix = imgName.substring(
        imgName.lastIndexOf(".") + 1, imgName.length);
    MultipartFile multipartFile = await MultipartFile.fromFile(
        image.path);
    FormData formData = FormData.fromMap({
       'file': multipartFile
      });
      //开始网络请求
    var response = await BaseNetwork.instance.dio.post(
        ApiAddress.userUpload, data: formData);
     if(response.data["success"]) {
     setState(() {
        //将返回的图片路径和对应id添加到_img和_imgId中
        this.imgPathList.add("${response.data["imagePath"]}");
        this.imgId.add("${response.data["id"]}");
      });
   }  
  }

  //删除图片
  void _deleteImg (int index) async {
    //将该图片和对应id分别从_img和_imgId中移除,可在此进行请求后端方法
      setState(() {
        this.imgPathList.removeAt(index);
        this.imageId.removeAt(index);
      });
  }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值