Flutter 拖拽控件Draggable看這一篇就夠了

程序員

微信

一枚編輯器

有態度ide

的程序員flex


注意:無特殊說明,Flutter版本及Dart版本以下:ui

  • Flutter版本:1.12.13+hotfix.5spa

  • Dart版本:2.7.0.net

Draggable系列組件可讓咱們拖動組件。3d

Draggable

Draggable組件有2個必須填寫的參數,child參數是子控件,feedback參數是拖動時跟隨移動的組件,用法以下:code

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系列總覽


本文分享自微信公衆號 - 老孟Flutter(lao_meng_qd)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索