我们在 flutter 中有 onTapDown 和 Drag 功能吗?
Do we have onTapDown and Drag functionality in flutter?
我有一个简单的用例,对于 flutter 的初学者来说有点棘手。
我需要这些值return用于下面解释的场景
一排有 2 个容器(绿色和橙色)
- 绿色容器上的 OnTapDown 应该 return ‘绿色’(这是直接完成的)
- 手指没有离开屏幕,我将手指拖到 Orange 容器上,我需要它 return ‘Orange’
我该如何解决?
一个解决方案可能是用 GestureDetector
包装您的布局并“猜测”元素的位置,然后知道拖动结束的位置。
编辑:感谢@GoodSp33d 评论:
class DragView extends StatefulWidget {
const DragView({Key? key}) : super(key: key);
@override
_DragViewState createState() => _DragViewState();
}
GlobalKey orangeContainerKey = GlobalKey();
GlobalKey greenContainerKey = GlobalKey();
class _DragViewState extends State<DragView> {
Rect? getGlobalPaintBounds(GlobalKey element) {
final renderObject = element.currentContext!.findRenderObject();
var translation = renderObject?.getTransformTo(null).getTranslation();
if (translation != null && renderObject?.paintBounds != null) {
return renderObject?.paintBounds
.shift(Offset(translation.x, translation.y));
} else {
return null;
}
}
bool isInRect(double x, double y, Rect? rect) {
if (rect != null)
return x >= rect.left &&
x <= rect.right &&
y <= rect.bottom &&
y >= rect.top;
return false;
}
@override
Widget build(BuildContext context) {
double _cursorX = 0;
double _cursorY = 0;
return GestureDetector(
onHorizontalDragUpdate: (details) {
_cursorX = details.globalPosition.dx;
_cursorY = details.globalPosition.dy;
},
onHorizontalDragEnd: (details) {
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey)))
print("Orange");
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(greenContainerKey)))
print("Green");
},
child: Row(
children: [
Expanded(
child: Container(key: greenContainerKey, color: Colors.green),
),
Expanded(
child: Container(key: orangeContainerKey, color: Colors.orange),
),
],
),
);
}
}
第二次编辑将检测移至 onDragUpdate 并检查以使其仅在矩形更改时发生:
GlobalKey? currentObject;
onHorizontalDragUpdate: (details) {
_cursorX = details.globalPosition.dx;
_cursorY = details.globalPosition.dy;
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey))) {
if (currentObject == null || currentObject != orangeContainerKey) {
print("Orange");
currentObject = orangeContainerKey;
}
}
if (isInRect(_cursorX, _cursorY,
getGlobalPaintBounds(greenContainerKey))) if (currentObject ==
null ||
currentObject != greenContainerKey) {
print("Green");
currentObject = greenContainerKey;
}
},
我有一个简单的用例,对于 flutter 的初学者来说有点棘手。
我需要这些值return用于下面解释的场景
一排有 2 个容器(绿色和橙色)
- 绿色容器上的 OnTapDown 应该 return ‘绿色’(这是直接完成的)
- 手指没有离开屏幕,我将手指拖到 Orange 容器上,我需要它 return ‘Orange’
我该如何解决?
一个解决方案可能是用 GestureDetector
包装您的布局并“猜测”元素的位置,然后知道拖动结束的位置。
编辑:感谢@GoodSp33d 评论:
class DragView extends StatefulWidget {
const DragView({Key? key}) : super(key: key);
@override
_DragViewState createState() => _DragViewState();
}
GlobalKey orangeContainerKey = GlobalKey();
GlobalKey greenContainerKey = GlobalKey();
class _DragViewState extends State<DragView> {
Rect? getGlobalPaintBounds(GlobalKey element) {
final renderObject = element.currentContext!.findRenderObject();
var translation = renderObject?.getTransformTo(null).getTranslation();
if (translation != null && renderObject?.paintBounds != null) {
return renderObject?.paintBounds
.shift(Offset(translation.x, translation.y));
} else {
return null;
}
}
bool isInRect(double x, double y, Rect? rect) {
if (rect != null)
return x >= rect.left &&
x <= rect.right &&
y <= rect.bottom &&
y >= rect.top;
return false;
}
@override
Widget build(BuildContext context) {
double _cursorX = 0;
double _cursorY = 0;
return GestureDetector(
onHorizontalDragUpdate: (details) {
_cursorX = details.globalPosition.dx;
_cursorY = details.globalPosition.dy;
},
onHorizontalDragEnd: (details) {
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey)))
print("Orange");
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(greenContainerKey)))
print("Green");
},
child: Row(
children: [
Expanded(
child: Container(key: greenContainerKey, color: Colors.green),
),
Expanded(
child: Container(key: orangeContainerKey, color: Colors.orange),
),
],
),
);
}
}
第二次编辑将检测移至 onDragUpdate 并检查以使其仅在矩形更改时发生:
GlobalKey? currentObject;
onHorizontalDragUpdate: (details) {
_cursorX = details.globalPosition.dx;
_cursorY = details.globalPosition.dy;
if (isInRect(
_cursorX, _cursorY, getGlobalPaintBounds(orangeContainerKey))) {
if (currentObject == null || currentObject != orangeContainerKey) {
print("Orange");
currentObject = orangeContainerKey;
}
}
if (isInRect(_cursorX, _cursorY,
getGlobalPaintBounds(greenContainerKey))) if (currentObject ==
null ||
currentObject != greenContainerKey) {
print("Green");
currentObject = greenContainerKey;
}
},