Flutter知识点: Drag

效果GIF

drag.gif

需求

  1. 7个可拖拽的色块
  2. 1个固定的随机颜色色块
  3. 同色块则计分

实现需要的Widget

  1. Draggable :一个可以被拖拽到DragTarget的widget
  2. DragTarget:一个用来接收被拖拽的Draggable的widget
  3. Positioned:定位

拆解

1.可拖拽的色块

 

  return Positioned(
      left: pos.dx,
      top: pos.dy,
      child: Draggable(
        data: widget.dragModel,
        child: Container(
          width: drag_item_height,
          height: drag_item_height,
          color: widget.dragModel.itemBgColor,
          child: Center(
            child: Text(
              widget.dragModel.itemName,
              style: TextStyle(
                color: Colors.white,
                decoration: TextDecoration.none,
                fontSize: 12.0,
              ),
            ),
          ),
        ),
        onDraggableCanceled: (velocity, offset) {
          if (!mounted) return;
          setState(() {
            //坐标是根据全屏算的,需要计算appbar和statusBar的高度

            double dx = offset.dx;
            double dy = offset.dy - appBarHeight - statusBarHeight;

            //临界点判断
            if (dx < 0) {
              dx = 0.0;
            }

            if (dx > screenWidth - drag_item_height) {
              dx = screenWidth - drag_item_height;
            }

            if (dy < 0) {
              dy = 0.0;
            }

            if (offset.dy + drag_item_height > screenHeight) {
              dy = screenHeight -
                  drag_item_height -
                  appBarHeight -
                  statusBarHeight;
            }

            pos = new Offset(dx, dy);

          });
        },
        feedback: Container(
          width: drag_item_height,
          height: drag_item_height,
          color: widget.dragModel.itemBgColor.withOpacity(0.5),
          child: Center(
            child: Text(
              widget.dragModel.itemName,
              style: TextStyle(
                color: Colors.white,
                decoration: TextDecoration.none,
                fontSize: 14.0,
              ),
            ),
          ),
        ),
      ));

2.随机色块,接收被拖拽的色块

 

@override
Widget build(BuildContext context) {
  return Positioned(
    right: 0.0,
    child: DragTarget(
      onAccept: (DragModel model) {
        if (model.itemBgColor == _curRandomColor) {
          _score++;
        }
      },
      builder: (
        BuildContext context,
        List<dynamic> accepted,
        List<dynamic> rejected,
      ) {
        return Container(
          width: 200.0,
          height: 200.0,
          decoration: BoxDecoration(
            color: _curRandomColor,
          ),
          child: Center(
            child: Text(
              "放入正确的颜色\n您的得分:$_score",
              style: new TextStyle(fontSize: 16.0, color: Colors.white),
            ),
          ),
        );
      },
    ),
  );
}

3.组合

 

@override
 Widget build(BuildContext context) {
   return new Scaffold(
     appBar: _buildAppbar(),
     body: new Stack(
       children: <Widget>[
         new DragItem(new DragModel(Offset(0.0, 0.0), '红', Colors.red)),
         new DragItem(new DragModel(
             Offset(0.0, 1 * drag_item_height), '橙', Colors.orange)),
         new DragItem(new DragModel(
             Offset(0.0, 2 * drag_item_height), '黄', Colors.yellow)),
         new DragItem(new DragModel(
             Offset(0.0, 3 * drag_item_height), '绿', Colors.green)),
         new DragItem(new DragModel(
             Offset(0.0, 4 * drag_item_height), '青', Colors.indigoAccent)),
         new DragItem(new DragModel(
             Offset(0.0, 5 * drag_item_height), '蓝', Colors.blue)),
         new DragItem(new DragModel(
             Offset(0.0, 6 * drag_item_height), '紫', Colors.purple)),
         new DragDestination(),
       ],
     ),
   );
 }

已有项目集成到Flutter代码已经上传到我的GITHUB

知乎日报Flutter版代码已经上传到我的GITHUB

基础学习过程中的代码都放在GITHUB

每天学一点,学到Flutter发布正式版!



作者:老实巴交的读书人
链接:https://www.jianshu.com/p/410fb2c9da4b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值