zoukankan      html  css  js  c++  java
  • flutter中用GridView撸出可拖拽,删除,上传等图片操作

    import 'package:flutter/material.dart';
    import 'package:n9a_crm/widgets/tip/tip.dart';

    class ProductImg extends StatefulWidget {
      @override
      _ProductImgState createState() => _ProductImgState();
    }

    class _ProductImgState extends State<ProductImg> {
      var _imgs = [
        "http://img5.mtime.cn/mg/2020/04/02/100052.90885849.jpg",
        "http://img5.mtime.cn/mg/2020/03/30/104612.95383214.jpg",
        "http://img5.mtime.cn/mg/2020/04/07/092906.73796826.jpg",
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn12%2F0%2Fw640h960%2F20180426%2F356f-fzrwiay9756380.jpg&refer=http%3A%2F%2Fn.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1619680186&t=6098cb2d8c6588bdbc7d2b4f27e6f133"
      ];
      String _movingValue; // 记录正在移动的数据

      _deleImg(String value) {
        setState(() {
          this._imgs.remove(value);
        });
      }

      // 生成GridView的items
      List<Widget> buildItems() {
        List<Widget> items = List<Widget>();
        _imgs.forEach((value) {
          items.add(draggableItem(value));
        });
        items.add(UpBtn(imgList: _imgs));
        return items;
      }

      // 生成可拖动的item
      Widget draggableItem(value) {
        return Draggable(
          data: value,
          child: DragTarget(
            builder: (context, candidateData, rejectedData) {
              return baseItem(value);
            },
            onWillAccept: (moveData) {
              print('=== onWillAccept: $moveData ==> $value');

              var accept = moveData != null;
              if (accept) {
                exchangeItem(moveData, value, false);
              }
              return accept;
            },
            onAccept: (moveData) {
              print('=== onAccept: $moveData ==> $value');
              exchangeItem(moveData, value, true);
            },
            onLeave: (moveData) {
              print('=== onLeave: $moveData ==> $value');
            },
          ),
          feedback: Container(
               110,
              height: 110,
              child: ClipRRect(
                  borderRadius: BorderRadius.all(Radius.circular(5)),
                  child: Image.network(
                    value,
                    fit: BoxFit.cover,
                  ))),
          childWhenDragging: null,
          onDragStarted: () {
            print('=== onDragStarted');
            setState(() {
              _movingValue = value; //记录开始拖拽的数据
            });
          },
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            print('=== onDraggableCanceled');
            setState(() {
              _movingValue = null; //清空标记进行重绘
            });
          },
          onDragCompleted: () {
            print('=== onDragCompleted');
          },
        );
      }

      // 基础展示的item 此处设置width,height对GridView 无效,主要是偷懒给feedback用
      Widget baseItem(value, [bgColor]) {
        if (value == _movingValue) {
          return Container();
        }
        return Stack(
          children: [
            Container(
                 double.infinity,
                height: double.infinity,
                color: bgColor,
                child: ClipRRect(
                    borderRadius: BorderRadius.all(Radius.circular(5)),
                    child: Image.network(
                      value,
                      fit: BoxFit.cover,
                    ))),
            Positioned(
              child: GestureDetector(
                onTap: () => _deleImg(value),
                behavior: HitTestBehavior.translucent,
                child: Image.asset('assets/product/close.png'),
              ),
              top: 0,
              right: 0,
            )
          ],
        );
      }

      // 重新排序
      void exchangeItem(moveData, toData, onAccept) {
        setState(() {
          var toIndex = _imgs.indexOf(toData);

          _imgs.remove(moveData);
          _imgs.insert(toIndex, moveData);

          if (onAccept) {
            _movingValue = null;
          }
        });
      }

      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              alignment: Alignment.centerLeft,
              margin: EdgeInsets.only(left: 15, top: 10, bottom: 10),
              child: Text(
                '产品图片',
                style: TextStyle(color: Color(0xff888888), fontSize: 15),
              ),
            ),
            Tip(text: '支持 jpg、png格式,拖动图片重新排序,默认第一张图片为主图,建议每张上传文件大小200K以内'),
            Container(
              margin: EdgeInsets.only(
                top: 15,
                left: 15,
                right: 15,
              ),
              child: GridView(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, mainAxisSpacing: 15, crossAxisSpacing: 15, childAspectRatio: 1),
                children: buildItems(),
                shrinkWrap: true,
                physics: NeverScrollableScrollPhysics(), //禁止滚动
              ),
            ),
          ],
        );
      }
    }

    //添加图片
    class UpBtn extends StatefulWidget {
      final imgList;
      UpBtn({Key key, this.imgList}) : super(key: key);
      @override
      _UpBtnState createState() => _UpBtnState();
    }

    class _UpBtnState extends State<UpBtn> {
      //选择相册照片
      Future getImage() async {
        var imageUrl = await ImagePicker().getImage(source: ImageSource.gallery);
        setState(() {
          widget.imgList.add(imageUrl);
        });
        print(widget.imgList);
      }

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: getImage,
          child: Container(
            decoration: BoxDecoration(
              color: Color(0xfff7f7f7),
              borderRadius: BorderRadius.all(Radius.circular(5)),
            ),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  margin: EdgeInsets.only(bottom: 5),
                  child: Image.asset(
                    'assets/product/addimg.png',
                  ),
                ),
                Text('添加图片', style: TextStyle(fontSize: 13, color: Color(0xff888888)))
              ],
            ),
          ),
        );
      }
    }
    //效果如下,可拖动,拿走不谢
    本人小白,各位想踏入前端的,我们可以一起学习,欢迎程序员大佬的指点
  • 相关阅读:
    AcWing 826. 单链表
    AcWing 803. 区间合并
    codeforces Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid
    球球大作战.exe
    RGB MIXER三原色混色器的制作
    125. 验证回文串
    110. 平衡二叉树
    112. 路径总和
    111. 二叉树的最小深度
    100. 相同的树
  • 原文地址:https://www.cnblogs.com/xiao-lei-ge/p/14653702.html
Copyright © 2011-2022 走看看