注意:無特殊說明,Flutter版本及Dart版本如下:
- Flutter版本: 1.12.13+hotfix.5
- Dart版本: 2.7.0
Draggable系列元件可以讓我們拖動元件。
Draggable
Draggable元件有2個必須填寫的引數,child
引數是子控制元件,feedback
引數是拖動時跟隨移動的元件,用法如下:
Draggable(
child: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10)
),
child: Text('孟',style: TextStyle(color: Colors.white,fontSize: 18),),
),
feedback: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10)
),
child: Text('孟',style: TextStyle(color: Colors.white,fontSize: 18),),
),
)複製程式碼
效果如下:
藍色的元件是feedback
,如果想在拖動的時候子元件顯示其他樣式可以使用childWhenDragging
引數,用法如下:
Draggable(
childWhenDragging: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(10)),
child: Text(
'孟',
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
...
)複製程式碼
效果如下:
我們還可以控制拖動的方向,比如只允許垂直方向移動,程式碼如下:
Draggable(
axis: Axis.vertical,
...
)複製程式碼
Draggable元件為我們提供了4中拖動過程中的回撥事件,用法如下:
Draggable(
onDragStarted: (){
print('onDragStarted');
},
onDragEnd: (DraggableDetails details){
print('onDragEnd:$details');
},
onDraggableCanceled: (Velocity velocity, Offset offset){
print('onDraggableCanceled velocity:$velocity,offset:$offset');
},
onDragCompleted: (){
print('onDragCompleted');
},
...
)複製程式碼
說明如下:
- onDragStarted:開始拖動時回撥。
- onDragEnd:拖動結束時回撥。
- onDraggableCanceled:未拖動到DragTarget控制元件上時回撥。
- onDragCompleted:拖動到DragTarget控制元件上時回撥。
Draggable有一個data
引數,這個引數是和DragTarget配合使用的,當使用者將控制元件拖動到DragTarget時此資料會傳遞給DragTarget。
DragTarget
DragTarget就像他的名字一樣,指定一個目的地,Draggable元件可以拖動到此控制元件,用法如下:
DragTarget(
builder: (BuildContext context, List<dynamic> candidateData,
List<dynamic> rejectedData) {
...
}
)複製程式碼
當onWillAccept
返回true時, candidateData
引數的資料是Draggable的data
資料。
當onWillAccept
返回false時, rejectedData
引數的資料是Draggable的data
資料,
DragTarget有3個回撥,說明如下:
- onWillAccept:拖到該控制元件上時呼叫,需要返回true或者false,返回true,鬆手後會回撥onAccept,否則回撥onLeave。
- onAccept:onWillAccept返回true時,使用者鬆手後呼叫。
- onLeave:onWillAccept返回false時,使用者鬆手後呼叫。
用法如下:
var _dragData;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: <Widget>[
_buildDraggable(),
SizedBox(
height: 200,
),
DragTarget<Color>(
builder: (BuildContext context, List<Color> candidateData,
List<dynamic> rejectedData) {
print('candidateData:$candidateData,rejectedData:$rejectedData');
return _dragData == null
? Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.red)),
)
: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10)),
child: Text(
'孟',
style: TextStyle(color: Colors.white, fontSize: 18),
),
);
},
onWillAccept: (Color color) {
print('onWillAccept:$color');
return true;
},
onAccept: (Color color) {
setState(() {
_dragData = color;
});
print('onAccept:$color');
},
onLeave: (Color color) {
print('onLeave:$color');
},
),
],
),
);
}
_buildDraggable() {
return Draggable(
data: Color(0x000000FF),
child: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(10)),
child: Text(
'孟',
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
feedback: Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(10)),
child: DefaultTextStyle.merge(
style: TextStyle(color: Colors.white, fontSize: 18),
child: Text(
'孟',
),
),
),
);
}複製程式碼
效果如下:
LongPressDraggable
LongPressDraggable繼承自Draggable,因此用法和Draggable完全一樣,唯一的區別就是LongPressDraggable觸發拖動的方式是長按,而Draggable觸發拖動的方式是按下。
今天的文章對大家是否有幫助?如果有,請在文章底部留言和點贊,以表示對我的支援,你們的留言、點贊和轉發關注是我持續更新的動力! 我建立了一個關於Flutter的微信交流群,歡迎您的加入,讓我們一起學習,一起進步,開始我們的故事,生活不止眼前的苟且,還有詩和《遠方》。 ==微信:mqd_zzy==
當然我也非常希望您關注我個人的公眾號,裡面有各種福利等著大家哦。