Draggable 是Flutter中的一個能夠拖拽到DragTarget的Widget。而且,他能夠把本身攜帶的數據傳遞給DragTarget。當Draggable被拖動到DragTarget的時候,DragTarget會判斷是否是須要接收傳遞過來的數據,在接收後作相應的狀態改變。java
Object -> Diagnosticable -> DiagnosticableTree -> Widget ->StatefulWidget -> Draggablegit
Draggable({Key key,
@required Widget child,
@required Widget feedback,
T data,
Axis axis,
Widget childWhenDragging,
Offset feedbackOffset: Offset.zero,
DragAnchor dragAnchor: DragAnchor.child,
Axis affinity,
int maxSimultaneousDrags,
VoidCallback onDragStarted,
DraggableCanceledCallback onDraggableCanceled,
DragEndCallback onDragEnd,
VoidCallback onDragCompleted,
bool ignoringFeedbackSemantics: true })
複製代碼
示例1:github
代碼以下:bash
import 'package:flutter/material.dart';
class DraggableTest extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return DraggableState();
}
}
class DraggableState extends State<DraggableTest> {
Offset _offset = Offset(100, 100);
double _width = 120.0;
String url =
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1564055541946&di=6da25e7ef3c905ce81d5e75694b62c19&imgtype=0&src=http%3A%2F%2Fimg4q.duitang.com%2Fuploads%2Fitem%2F201407%2F02%2F20140702203112_BGFPv.thumb.700_0.jpeg";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DraggableDemo"),
),
body: Transform.translate(
offset: _offset,
child: Draggable(
child: Image.network(url, width: _width),
feedback: Image.network(url, width: _width),
childWhenDragging: Image.network(url, width: _width),
onDraggableCanceled: (v, o) {
setState(() {
_offset = o;
print("dx:" + o.dx.toString());
print("dy:" + o.dy.toString());
});
},
onDragCompleted: () {
print("onDragCompleted");
},
onDragEnd: (dragEndDetails) {
setState(() {
_offset = dragEndDetails.offset;
});
print("onDragEnd");
print(" dragEndDetails.offset:" +
dragEndDetails.offset.toString());
},
)));
}
}
複製代碼
除此以外,咱們也能夠修改一下代碼,childWhenDragging參數傳入一個不可見的Widget,用於實現相似於GestureDetector 的拖拽平移功能。app
示例2:ide
代碼以下:函數
import 'package:flutter/material.dart';
class DraggableTest extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return DraggableState();
}
}
class DraggableState extends State<DraggableTest> {
Offset _offset = Offset(100, 100);
double _size = 150.0;
String url =
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1564055541946&di=6da25e7ef3c905ce81d5e75694b62c19&imgtype=0&src=http%3A%2F%2Fimg4q.duitang.com%2Fuploads%2Fitem%2F201407%2F02%2F20140702203112_BGFPv.thumb.700_0.jpeg";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DraggableDemo"),
),
body: Transform.translate(
offset: _offset,
child: Draggable(
child: Image.network(url, width: _size),
feedback: Image.network(url, width: _size),
childWhenDragging: Container(
width: 0,
height: 0,
),
onDragEnd: (dragEndDetails) {
setState(() {
_offset = dragEndDetails.offset;
print(" onDragEnd - dragEndDetails.offset:" +
dragEndDetails.offset.toString());
});
},
)));
}
}
複製代碼
log 輸出:測試
2019-08-09 17:01:18.492 15029-15061/com.xiaosong.flutterwidgets I/flutter: onDragStarted
2019-08-09 17:01:20.091 15029-15061/com.xiaosong.flutterwidgets I/flutter: onDragEnd - dragEndDetails.offset:Offset(57.7, 370.0)
2019-08-09 17:01:20.091 15029-15061/com.xiaosong.flutterwidgets I/flutter: dx:57.66666666666674, dy:370.0000000000001
2019-08-09 17:01:23.385 15029-15061/com.xiaosong.flutterwidgets I/flutter: onDragStarted
2019-08-09 17:01:23.878 15029-15061/com.xiaosong.flutterwidgets I/flutter: onDragEnd - dragEndDetails.offset:Offset(114.0, 274.3)
2019-08-09 17:01:23.878 15029-15061/com.xiaosong.flutterwidgets I/flutter: dx:114.00000000000007, dy:274.3333333333334
複製代碼
從log 能夠看到,若是沒有與DragTarget 配合使用,它不會觸發 onDragCompleted 或者 onDraggableCanceled 回調。而onDragStarted、onDragEnd 依舊會觸發。ui
本篇文章咱們大體講解了Draggable的基本概念及經常使用示例。因爲Draggable 沒有 GestureDetector中相似onPanUpdate的監聽,所以觸發onDragEnd 的position 並非很是精準。若咱們須要拖拽平移Widget,通常來講仍是建議經過GestureDetector去實現,Draggable通常是搭配DragTarget去使用的。下篇文章咱們將講解如何搭配DragTarget來實現拖拽狀態並改變數據。url
xiaosongzeem |