I want to drag an image on top of another image at any position. The problem is that Draggable Widget returns the Widget back to initial position after I release the touch, also Drag Target only accepts one fixed position. Any idea?
Thanks
You can use the onAccept parameter of the Draggable widget & update the offset value of the widget that's passed to your function as an argument:
Draggable(
offset: Offset(xFromState, yFromState)
onAccept: (value) {
// Do something with the DragTarget value here
}
)
Related
I have ListView.builder with horizontal scrolling (a custom top navigation bar). As I scroll to the right and left, the 'selectedIndex' is changing, but the UI inside this widget isn't showing this change in position. I'd like to 'Jump To' the selected index upon swiping.
Here's how my ListView is currently updating its index:
void onChanged(int index) {
pageController.jumpToPage(index);
setState(() {
this.selectedIndex = index;
});
}
How can I accomplish this? Any guidance would mean a lot.
Thanks, A.V.
You can calculate selected item offset by item width and height and then use
_gridViewController.jumpTo(calculatedOffset);
Is it possible to use GestureDetector — specifically the onTapUp gesture — inside of an InteractiveViewer?
I know InteractiveViewer uses a GestureDetector itself and overrides the onScaleEnd, onScaleStart, and onScaleUpdate methods to implement panning. However, onTapUp is not overriden, which makes me think there's potential to use it.
I did some digging around and found this in the InteractiveViewer's TransformationController documentation for the toScene() method:
Return the scene point at the given viewport point.
A viewport point is relative to the parent while a scene point is
relative to the child, regardless of transformation. Calling toScene
with a viewport point essentially returns the scene coordinate that
lies underneath the viewport point given the transform.
The viewport transforms as the inverse of the child (i.e. moving the
child left is equivalent to moving the viewport right).
This method is often useful when determining where an event on the
parent occurs on the child. This example shows how to determine where
a tap on the parent occurred on the child.
GestureDetector(
onTapUp: (TapUpDetails details) {
_childWasTappedAt = _transformationController.toScene(
details.localPosition,
);
},
child: InteractiveViewer(
transformationController: _transformationController,
child: child,
), ); }
So it seems that rather than having a GestureDetector as a child, the recommended solution is to wrap the InteractiveViewer with a GestureDetector, use a custom TransformationController, and get the position relative to the viewer viewport from this controller.
Ive create a popup menu widget which takes two arguments :a button widget, and a menu widget . When the button is pressed the menu widget is passed to an OverlayEntry as the child which is then added to the Overlay.of(context)
I'd like the resulting display to be as such:
O (Button)
____|____
| MENU |
|_______|
I can place the menu widget inside a Positioned Widget to move it freely around the Overlay, but I dont know how to get the correct coordinates. I can get the center of the Button by finding it's Renderbox, but I cant know the size, and therefore the correct position, of the Menu until after it's draw (as it can be any widget).
Is there some soft of layout option to tell a Widget of any size to vertically or horzontally align itself with a given coordinate?
To get the size of a widget:
First give your Widget a key:
key: _key,
Then you can get the size(and position) like this:
_getSize() {
final RenderBox renderBox = _key.currentContext.findRenderObject();
final size = renderBox.size;
final position = renderBox.localToGlobal(Offset.zero);
final height = size.height; //same for width
}
I have a Scrollable (ListView or any other) and it contains a transparent widget, say Container(height:200). I can see through both the widget and the scrollable (in other words I can see the widgets behind the scrollable).
How can I be able to click through the transparent widget and the scrollable, so that I reach the widgets behind the scrollable?
ListView(
children: [
Container(height: 200), // Transparent.
Container(color: Colors.red, height: 200),
],
);
Note, I cannot wrap the scrollable with IgnorePointer, because I still want to click the non-transparent widgets in the scrollable.
The only reasonable solution I can think of is to have a GestureDetector on the transparent container, which will give you the global position of the taps:
GestureDetector(
onTapUp: (TapUpDetails tapUpDetails) {
print("onTapUp global: " + tapUpDetails.globalPosition.toString());
},
And then add a Key to the widget behind the list, and use it to get the global position of the top left corner of the widget's rectangle, as well as the size of the widget, and use those to get the rectangle of the widget:
RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;
If the background widget does not move, you can do it within initState on the very next frame using WidgetsBinding.instance.addPostFrameCallback (the render object will be null if do it synchronously within initState) and save the Rect - otherwise you will have to recalculate it on every tap.
And then finally on each tap on the transparent container you can calculate whether the tap's position is within the boundaries of the background widget, and invoke the corresponding code:
// if tap is within boundaries of the background widget
if (rectangle.contains(tapUpDetails.globalPosition)) {
// your code here
}
Here is an example of using Draggable.
Is there a possibility to get also like the touch coordinate within the Draggable widget? I illustrated what I'm searching for in the image with x1 and x2.
So I want to determine one of the inner coordinates like x1 or x2.
Here is how I use draggable so far.
draggable = new Draggable(
data: widget.text,
feedback: avatar,
child: item,
onDraggableCanceled: (velocity, offset) {
// the inner touch point is not included in offset ...
},
);
Draggable docs
If it doesn't work with Draggable. Is there an alternative which I can use?
You can wrap your draggable widget in a Listener and you can do the below code.
onPointerDown: (PointerEvent event) {
print("Touch Position Of your Widget ${event.position}");
},