如何在 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/
您需要在 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,
),
));
}
}
我想知道如何在 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/
您需要在 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,
),
));
}
}