2021-07-16 Flutter项目中的 drag 和 drop

拖拽控件在移动端是很常见的需求,最近我们项目中也用到了,之前在iOS端实现过,很麻烦,flutter中实现起来就很方便,在此记录一下:

要将一个 Widget 变为可拖拽的,只需要将 Widget 用 LongPressDraggable 包裹起来就可以,其中 child 和 feedback 参数是必须的:

1、child 参数 表示普通状态下的视图
2、feedback 参数 表示 长按后出现的视图
3、data 参数 表示传递的数据
4、dragAnchorStrategy 参数表示 feedback 视图的展示方式:

  • pointerDragAnchorStrategy 表示 feedback 视图会跟随用户手指移动而移动
  • childDragAnchorStrategy 表示 feedback 视图 会直接出现在 child 视图上方
LongPressDraggable(
      data: model,
      dragAnchorStrategy: pointerDragAnchorStrategy,
      feedback: DraggingARTyreWidget(dragKey: draggableKey, model: model),
      child: ARTyreWidget(
        model: model,
        highlighted: (candidateItems.isNotEmpty &&
            !candidateItems.contains(model)),
      ),
    );

这样之后,ARTyreWidget 控件就变得可以拖拽了,还需要将其他控件变为响应 drop 事件
将 Widget 用 DragTarget 包裹起来就可以了,参数 builder 必须:
1、builder 参数 构建视图

typedef DragTargetBuilder = Widget Function(BuildContext context, List candidateData, List rejectedData);
  • 其中 candidateData 表示 用户当前正在拖拽的视图的数据中会被当前控件接受的数据,
  • rejectedData 表示 用户当前正在拖拽的视图的数据中不被当前控件接受的数据
    能否被当前控件接受通过范型和参数 onWillAccept 来决定
const DragTarget({
    Key? key,
    required this.builder,
    this.onWillAccept,
    this.onAccept,
    this.onAcceptWithDetails,
    this.onLeave,
    this.onMove,
    this.hitTestBehavior = HitTestBehavior.translucent,
  }) : super(key: key);

以下是我的实现

DragTarget(
      builder: (context, candidateItems, rejectedItems) {
        if (canMove) {
          return LongPressDraggable(
            data: model,
            dragAnchorStrategy: pointerDragAnchorStrategy,
            feedback: DraggingARTyreWidget(dragKey: draggableKey, model: model),
            child: ARTyreWidget(
              model: model,
              highlighted: (candidateItems.isNotEmpty &&
                  !candidateItems.contains(model)),
            ),
          );
        } else {
          return ARTyreWidget(
            model: model,
            highlighted:
                (candidateItems.isNotEmpty && !candidateItems.contains(model)),
          );
        }
      },
      onAccept: (value) {
        if ((model?.position.isNotEmpty ?? false) &&
            value.position != model?.position) {
          /// MARK: 不同的位置可以交换
          AssetsReceiveListItemDetailPageController? _controller =
              Get.find();
          num? carrierId = _controller.detailModel?.carrierId;
          String? fromPosition = value.position;
          String? toPosition = model?.position;
          logD(
              "#####carrierId:$carrierId -- 原始轮位:$fromPosition -- 目标轮位:$toPosition");
          if (carrierId != null &&
              (fromPosition.isNotEmpty) &&
              (toPosition?.isNotEmpty ?? false)) {
            HttpManager.requestMoveWheel(
                    carrierId: carrierId,
                    fromPosition: fromPosition,
                    toPosition: toPosition!)
                .then((value) {
              if (value) {
                _controller.requestDetailData();
              }
            });
          }
        }
      },
    );

效果图


效果图

你可能感兴趣的:(2021-07-16 Flutter项目中的 drag 和 drop)