Do we have onTapDown and Drag functionality in flutter?
111
One solution could be to wrap your layout with GestureDetector
and "guess" the position of your elements to then know where the drag ends.
EDIT: Adding a real check on the target position to make it more robust thanks to @GoodSp33d comment:
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),
),
],
),
);
}
}
Second edit moving the detection to the onDragUpdate and checks to make it happens only on rect changes:
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;
}
},
Author by
Alvey
Updated on December 31, 2022Comments
-
Alvey over 1 year
I have a simple usecase which is some how super tricky for a beginner in flutter.
I need these values returned for the scenario explained below
There are 2 containers in a row (green and orange)
- OnTapDown on green container it should return ‘Green’ (this is straight forward and done)
- Without lifting the finger off the screen, I drag my finger over the Orange container and I need that to return ‘Orange’
How do I solve this?
-
Alvey over 2 yearsI have tried using GestureDetector 'onTapDown' and also tried using Listener with these functions 'onPointerDown', 'onPointerMove' still not able to figure how to execute this
-
Yeasin Sheikh over 2 yearscheck this github.com/yeasin50/Rotary_phone_lock/blob/…
-
Colin Lazarini over 2 yearsDont forget to upvote and set mark it as resolved ;)
-
GoodSp33d over 2 yearsYou can assign keys to both green and orange containers and detect if touch point is in the container or not instead to make it more robust.
-
Alvey over 2 yearsHey, thanks for the quick reply I tried this, and it returns 'Orange' after Drag Ends right, but i need the value to be returned as soon as it reaches orange
-
Colin Lazarini over 2 yearsThen you need to calculate the position in the dragUpdate method and not end, but also add a check that if it is still the same container to not print or do anything.
-
Alvey over 2 years@Wapazz it works when i updated in drag update :) thanks
-
Colin Lazarini over 2 yearsI added to the answer to make it not refresh everytime