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(
          width: 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(
            width: 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)))
          ],
        ),
      ),
    );
  }
}
//效果如下,可拖动,拿走不谢

 

 

posted @ 2021-04-13 16:02  文磊啊~  阅读(1333)  评论(1编辑  收藏  举报