目录
1.Draggable
2.LongPressDraggable
3.DragTarget
4.GestureDetector
5.Dismissible
6.IgnorePointer
7.AbsorbPointer
一个可以展示拖动效果的小部件
文档
affinity → Axis:此部件与其它手势的竞争方式 在非affinity方向上不响应拖动事件
axis → Axis:限制部件的拖动方向
child → Widget:子部件
childWhenDragging → Widget:当拖动时显示的子部件(原位置)
data → T:
dragAnchor → DragAnchor:拖动时应该锚定的位置 指尖和子部件
feedback → Widget:当拖动时手指下显示的小部件
feedbackOffset → Offset:
ignoringFeedbackSemantics → bool:
maxSimultaneousDrags → int:同时支持拖动多少个点
onDragCompleted → VoidCallback:Dragragable被删除并被DragTarget接受时调用。
onDragEnd → DragEndCallback:拖动结束时调用
onDraggableCanceled → DraggableCanceledCallback:在没有被DragTarget接受的情况下松开draggable时调用。
onDragStarted → VoidCallback:拖动开始时调用
Draggable(
affinity: Axis.vertical,//限制响应拖动事件的方向
// axis: Axis.vertical,//限制拖动方向
child: Icon(Icons.home,size: 100.0),//子部件
childWhenDragging: Icon(Icons.home,size: 100.0,color:Colors.grey),//拖动时原点显示的部件
data: '123',
dragAnchor: DragAnchor.child,//拖动时锚点
feedback: Icon(Icons.home,size: 100.0),//拖动时指尖显示的部件
feedbackOffset: Offset.fromDirection(1.0),
ignoringFeedbackSemantics: true,
maxSimultaneousDrags: 1,
onDragCompleted: (){
//拖动完成时调用
//当动态删除此部件时 可能会调用此方法
print('拖动完成');
},
onDragEnd: (DraggableDetails details){
//拖动结束时调用
print('拖动结束');
},
onDraggableCanceled: (Velocity velocity, Offset offset){
//拖动未到目标点时候松手
print('拖动取消');
},
onDragStarted: (){
//开始拖动时调用
print('开始拖动');
},
);
效果
也可将拖动时原点位置部件内容未null 模拟展示拖动效果
即
childWhenDragging: Icon(null,size: 100.0,color:Colors.grey)
LongPressDraggable继承自Draggable 与Draggable 不同的是LongPressDraggable在长按时触发拖动开始事件
文档
效果 为了显示长按效果 将图标拖动图标改为了 Icons.cake
一个当松开Draggable部件时接收数据的部件
文档
builder → DragTargetBuilder
onAccept → DragTargetAccept
onLeave → DragTargetLeave
onWillAccept → DragTargetWillAccept
Draggable使用 1中的Draggable
class MyDragTargetTest extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyDraggable(),//可拖动部件
MyDragTarget(),//接收部件
],
);
}
}
class MyDragTarget extends StatelessWidget{
@override
Widget build(BuildContext context) {
String text = '';
return DragTarget(
builder: (BuildContext context, List candidateData, List rejectedData){
return Container(
height: 150.0,
child: Text(candidateData.length>0?candidateData.last:"无数据 接收到的数据$text"),
);
},
onAccept: (String data){
print('接收到了数据$data');
text = data;
},
onLeave: (String data){
print('携带数据$data离开');
},
onWillAccept: (String data){
//所有类型均接收
return true;
},
);
}
}
运行结果
一个可以检测手势的小部件
文档
behavior → HitTestBehavior:在事件执行过程中如何进行事件传递
HitTestBehavior.deferToChild :当至少有一个子部件可点击时才会响应事件
HitTestBehavior.opaque :可响应事件 并可防止其背后部件响应事件 即事件不可穿透
HitTestBehavior.translucent 可响应事件 并且其背后部件也可响应事件 即事件可穿透
child → Widget:子部件
dragStartBehavior → DragStartBehavior:何时开始响应拖动事件 DragStartBehavior.start 检测到拖动手势时即开始 DragStartBehavior.down 首次检测到down事件时才执行
excludeFromSemantics → bool:
onDoubleTap → GestureTapCallback:双击回调
onHorizontalDragCancel → GestureDragCancelCallback:横向滑动取消
onHorizontalDragDown → GestureDragDownCallback:按下事件 并且可能要开始横向滑动
onHorizontalDragEnd → GestureDragEndCallback:横向滑动结束
onHorizontalDragStart → GestureDragStartCallback:横向滑动开始
onHorizontalDragUpdate → GestureDragUpdateCallback:横向滑动回调
onVerticalDragCancel → GestureDragCancelCallback:纵向滑动取消
onVerticalDragDown → GestureDragDownCallback:按下事件 并且可能要开始纵向滑动
onVerticalDragEnd → GestureDragEndCallback:纵向滑动结束
onVerticalDragStart → GestureDragStartCallback:纵向滑动开始
onVerticalDragUpdate → GestureDragUpdateCallback:纵向滑动回调
onLongPress → GestureLongPressCallback:长按回调
onLongPressDragStart → GestureLongPressDragStartCallback:长按后可拖动回调
onLongPressDragUp → GestureLongPressDragUpCallback:长按(拖动)抬起回调
onLongPressDragUpdate → GestureLongPressDragUpdateCallback:长按拖动过程回调
onLongPressUp → GestureLongPressUpCallback:长按回调
onPanCancel → GestureDragCancelCallback:onPan事件未完成回调
onPanDown → GestureDragDownCallback:已经接触屏幕并且可能要开始滑动
onPanEnd → GestureDragEndCallback:onPan事件结束回调
onPanStart → GestureDragStartCallback:已经接触屏幕并且已经开始滑动
onPanUpdate → GestureDragUpdateCallback:拖动过程回调
onScaleEnd → GestureScaleEndCallback:手指离开屏幕回调
onScaleStart → GestureScaleStartCallback:与屏幕接触的指针已建立焦点,初始比例为1.0
onScaleUpdate → GestureScaleUpdateCallback:新的焦点/比例回调。
onTap → GestureTapCallback:单击事件
onTapCancel → GestureTapCancelCallback:onTapDown事件不会执行
onTapDown → GestureTapDownCallback:可能导致tap事件的接触
onTapUp → GestureTapUpCallback:点击事件结束
一个可以拖动来隐藏部件的小部件
文档
background → Widget:放在子部件后面的小部件。 如果还指定了secondaryBackground,则只有在向下或向右拖动子项时才会显示此窗口小部件。
child → Widget:子部件
confirmDismiss → ConfirmDismissCallback:使程序可以控制滑动后是否隐藏部件
crossAxisEndOffset → double:拖动结束后非主轴偏移量
direction → DismissDirection:部件滑动方向
dismissThresholds → Map
movementDuration → Duration:超过指定时间后若未移除则回到原始位置
onDismissed → DismissDirectionCallback:子部件被移除时调用 若confirmDismiss返回true 则在此方法中必须移除指定子部件
onResize → VoidCallback:当大小发生改变时即拖动时调用
resizeDuration → Duration:滑动移除后延迟指定时间后调用onDismissed 若未null则立即调用
secondaryBackground → Widget:它隐藏在子部件后面,当子部件被向上或向左拖动时会显示。 只有在指定了背景时才可以指定它。
这里展示下官方的一个示例
class MyDismissible extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MyApp(
items: new List.generate(20, (i) => "Item ${i + 1}"),
);
}
}
class MyApp extends StatelessWidget {
final List items;
MyApp({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = 'Dismissing Items';
return new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
),
body: new ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return new Dismissible(
// Each Dismissible must contain a Key. Keys allow Flutter to
// uniquely identify Widgets.
key: new Key(item),
// We also need to provide a function that will tell our app
// what to do after an item has been swiped away.
onDismissed: (direction) {
items.removeAt(index);
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("$item dismissed")));
},
// Show a red background as the item is swiped away
background: new Container(color: Colors.red),
child: new ListTile(title: new Text('$item')),
);
},
),
),
);
}
}
运行结果
一个可以屏蔽触碰事件的部件
文档
ignoring → bool:是否屏蔽自身及子部件触碰事件
ignoringSemantics → bool:
child → Widget:子部件
一个可以拦截触碰事件的部件
文档
absorbing → bool:是否拦截子部件触碰事件
ignoringSemantics → bool:
child → Widget:子部件