如何在 Flutter 中开始拖动 Widget 时显示图标

How to show Icon when I started dragging a Widget in Flutter

我想知道如何在 LongPressDraggable 小部件中开始拖动容器时在屏幕底部显示删除图标

Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () => _onTap(context),
        child: LongPressDraggable(
          data: index,
          maxSimultaneousDrags: 1,
          onDragUpdate: (details) => print('update'),
          onDragStarted: () => _buildDragTarget(),
          onDragEnd: (_) => print('end'),
          feedback: Material(
            child: Container(
              height: Sizes.height / 4.5,
              width: Sizes.height / 4.5,
              child: _DraggableContent(
                index: index,
                place: place,
              ),
            ),
          ),
          childWhenDragging: Container(color: Colors.transparent),
          child: _DraggableContent(
            index: index,
            place: place,
          ),
        ));
  }

 Widget _buildDragTarget() {
    return DragTarget<int>(
      builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
        return Icon(Icons.delete);
      },
      onAcceptWithDetails: (DragTargetDetails<int> dragTargetDetails) {
        print('onAcceptWithDetails');
        print('Data: ${dragTargetDetails.data}');
        print('Offset: ${dragTargetDetails.offset}');
      },
    );
  }

目前,当我开始拖动项目时,发生了任何事情,我不知道如何继续

这里有一个可拖动小部件的示例:https://blog.logrocket.com/drag-and-drop-ui-elements-in-flutter-with-draggable-and-dragtarget/

丢弃物品部分https://blog.logrocket.com/drag-and-drop-ui-elements-in-flutter-with-draggable-and-dragtarget/#:~:text=the%20tomato%20image.-,Dropping%20an%20item,-At%20this%20point

您需要在 DragTarget 小部件上使用 onAccept 事件:

onAccept: (data) {
setState(() {
  showSnackBarGlobal(context, 'Dropped successfully!');
  _isDropped = true;
});
},

并且在拖动开始时,您可以使用此事件显示删除图标 (https://blog.logrocket.com/drag-and-drop-ui-elements-in-flutter-with-draggable-and-dragtarget/#:~:text=Listening%20to%20drag%20events):

onDragStarted: () {
showSnackBarGlobal(context, 'Drag started');
},

希望对你有所帮助

据我了解,您需要在拖动对象时在底部显示删除图标。 您可以使用 Visibility 小部件包裹删除图标,并根据拖动 activity.

它将是这样的:

Widget _buildDragTarget() {
  return DragTarget<int>(
    builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
      return Visibility(
          visible: isDragEnable,
          child: Icon(Icons.delete));
    },
    onAcceptWithDetails: (DragTargetDetails<int> dragTargetDetails) {
      print('onAcceptWithDetails');
      print('Data: ${dragTargetDetails.data}');
      print('Offset: ${dragTargetDetails.offset}');
    },
  );
}

我找到了解决方案。它可以创建 BlocProvider 并使用状态。

class _Trash extends StatefulWidget {
  const _Trash({
    Key key,
  }) : super(key: key);

  @override
  __TrashState createState() => __TrashState();
}

class __TrashState extends State<_Trash> with SingleTickerProviderStateMixin {
  Animation animation;
  AnimationController controller;

  _listenerManager(bool isDragging) {
    if (isDragging) {
      setState(() => animation =
          CurvedAnimation(parent: controller, curve: Curves.elasticOut));
      controller.forward();
    } else {
      setState(() => animation = CurvedAnimation(
          parent:
              CurvedAnimation(parent: controller, curve: Interval(0.75, 1.0)),
          curve: Curves.ease));
      controller.reverse();
    }
  }

  _deleteWidget(data) {
    BlocProvider.of<BoardBloc>(context).add(BoardEvent.delete(data));
  }

  @override
  void initState() {
    controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        bottom: 0,
        left: Sizes.width / 2 - Sizes.height / 15 / 2,
        child: ScaleTransition(
            scale: animation,
            child: BlocListener<BoardBloc, BoardState>(
              listenWhen: (previous, current) =>
                  previous.isDragging != current.isDragging,
              listener: (context, state) => _listenerManager(state.isDragging),
              child: Container(
                height: Sizes.height / 15,
                width: Sizes.height / 15,
                color: Colors.amber,
                child: DragTarget<int>(
                  builder: (BuildContext context, List<int> data,
                      List<dynamic> rejects) {
                    return Icon(Icons.delete);
                  },
                  onAcceptWithDetails:
                      (DragTargetDetails<int> dragTargetDetails) {
                    _deleteWidget(dragTargetDetails.data);
                    print('onAcceptWithDetails');
                    print('Data: ${dragTargetDetails.data}');
                    print('Offset: ${dragTargetDetails.offset}');
                  },
                ),
              ),
            )));
  }
}

class _PlaceTile extends StatelessWidget {
  final int index;
  final Place place;
  const _PlaceTile({@required this.place, @required this.index});

  _onTap(BuildContext context) => Navigator.of(context).push(PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) =>
          PlaceViewer(index: index, animation: animation, place: place)));

  _startDragging(context) {
    BlocProvider.of<BoardBloc>(context).add(BoardEvent.startedDragging());
  }

  _stopDragging(context) {
    BlocProvider.of<BoardBloc>(context).add(BoardEvent.stopDragging());
  }

  _dragging(context) {
    BlocProvider.of<BoardBloc>(context).add(BoardEvent.dragging());
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () => _onTap(context),
        child: LongPressDraggable(
          data: index,
          maxSimultaneousDrags: 1,
          onDragUpdate: (details) => _dragging(context),
          onDragStarted: () => _startDragging(context),
          onDragEnd: (_) => _stopDragging(context),
          feedback: Material(
            child: Container(
              height: Sizes.height / 4.5,
              width: Sizes.height / 4.5,
              child: _DraggableContent(
                index: index,
                place: place,
              ),
            ),
          ),
          childWhenDragging: Container(color: Colors.transparent),
          child: _DraggableContent(
            index: index,
            place: place,
          ),
        ));
  }
}