I'm trying to implement Smooth Scroll in a PageView, so I have set the physics property to NeverScrollableScrollPhysics() and I have wrapped the items in the builder fonction with a GestureDetector that detects Drag gestures.
When a drag gesture is detected, a function is triggered and the page will be change accordingly.
My problem is that on Flutter Web, the onVerticalDragGesture is only detected when dragging with three fingers, and nothing happens when swiping with two. Is there any way to solve this?
By the way, the result is the same with the onPanUpdate property.
Feel free to suggest other ways to implement Smooth Scroll. Thanks in advance, guys.
Here is my code if you want to reproduce it:
PageView.builder(
physics: NeverScrollableScrollPhysics(),
controller: /* PAGECONTROLLER */,
scrollDirection: Axis.vertical,
pageSnapping: false,
itemBuilder: (context, index) {
return GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
if (details.delta.dy > 5.0) {
/* FUNCTION TO MOVE TO PREVIOUS PAGE */
}
if (details.delta.dy < -5.0) {
/* FUNCTION TO MOVE TO NEXT PAGE */
}
},
child: /* PAGES OF THE PAGEVIEW, JUST USE EMPTY CONTAINERS WITH DIFFERENT COLORS */,
);
},
itemCount: /* NUMBER OF PAGES */,
),
By default, GestureDetector in Flutter only detects single finger gestures. To detect multi-finger gestures, you can use the Listener widget with a GestureRecognizer to recognize the multi-finger gesture.
Here's a code snippet that may helps using Listener and PanGestureRecognizer:
Listener(
onPointerDown: (event) {
if (event.kind == PointerDeviceKind.touch && event.pointer != 0) {
// A second finger is down, start recognizing the gesture
_gestureRecognizer.addPointer(event);
}
},
onPointerUp: (event) {
if (event.kind == PointerDeviceKind.touch && event.pointer != 0) {
// The second finger is up, stop recognizing the gesture
_gestureRecognizer.removePointer(event);
}
},
child: Container(
// Your widget tree
),
);
// Initialize the gesture recognizer in your widget state
PanGestureRecognizer _gestureRecognizer = PanGestureRecognizer()
..onStart = (details) {
// This is called when the gesture starts
// Check that it is a two-finger gesture before handling it
if (_gestureRecognizer.numberOfPointers == 2) {
// Handle the two-finger drag gesture
print('Two-finger drag started');
}
}
..onUpdate = (details) {
// This is called when the gesture is updated
// Check that it is a two-finger gesture before handling it
if (_gestureRecognizer.numberOfPointers == 2) {
// Handle the two-finger drag gesture
print('Two-finger drag updated');
}
}
..onEnd = (details) {
// This is called when the gesture ends
// Check that it is a two-finger gesture before handling it
if (_gestureRecognizer.numberOfPointers == 2) {
// Handle the two-finger drag gesture
print('Two-finger drag ended');
}
};
Related
I need to hide my FloatingActionButton when scrolling a SingleChildScrollView. I found something about how to hide it when the user scrolls down and then show it when the user scrolls up, but that's not what I'm looking for.
I want the button to remain hidden only during the scroll. I also tried playing with the NotificationListener but didn't come up with a solution
Hide until you don't get any more notifications.
NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (_show) setState(() => _show = false);
_timer?.cancel();
_timer = Timer(const Duration(milliseconds: 200), () => setState(() => _show = true));
return true;
},
child: <your widget>
)
Im working on flutter web.
I need to implement finger touch specific code and mouse specific codes.
I have used Listener widget.but it recognizes both mouse panning and finger panning on screen.
But I need only mouse panning.
Kindly tell me the code which differentiate between finger touch gestures and mouse pointer gestures.
Listener code:
Listener(
onPointerMove: (details) {
print('moved');
},
child: Container(height:500,width:300));
From the TapDownDetails you can get the PointerDeviceKind. Please refer the below code.
GestureDetector(
onTapDown: (TapDownDetails details){
PointerDeviceKind pointerType = details.kind;
}
);
In Listener
Listener(
onPointerMove: (details) {
print('moved');
},
onPointerDown: (details){
PointerDeviceKind pointerType = details.kind
},
child: Container(height:500,width:300));
I've already tried:
#override
void didChangeDependencies() {
super.didChangeDependencies();
Orientation orientation = MediaQuery.of(context).orientation;
(orientation == Orientation.portrait)
? print(orientation)
: Navigator.pop(context);
}
in the _BottomContentState but that gives me an error when I switch the orientation of the device.
Additionally I want the ModalBottomSheet to close if it is open, otherwise no action
You could use an OrientationBuilder widget to programatically close your modal bottom sheet.
OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.landscape) {
// Close your modal
}
}
);
how to detect middle or three-quarters of scroll position on ListView? I want to get data after reach to middle or three-quarters of the scroll position. How to do it?
Currently, I get data on the end of listView.
_scrollController.addListener(scrollListener);
void scrollListener(){
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
getMoreData();
}
}
I think this would work..
_scrollController.addListener(scrollListener);
void scrollListener(){
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent * 0.75) {
getMoreData();
}
}
I am using GestureDetector and didn't find any onXYZ event which tells you the direction of drag.
Did you try onPanUpdate(details) method? Here is how you can do it.
GestureDetector(
onPanUpdate: (details) {
if (details.delta.dx > 0)
print("Dragging in +X direction");
else
print("Dragging in -X direction");
if (details.delta.dy > 0)
print("Dragging in +Y direction");
else
print("Dragging in -Y direction");
},
child: Container(
color: Colors.blue,
width: double.infinity,
height: double.infinity,
),
)
Note: This callback causes a crash if onHorizontalDragUpdate() or onVerticalDragUpdate() is also provided as mentioned by anmol.majhail.
For those, who have "Having both a pan gesture recognizer and a scale gesture recognizer is redundant; scale is a superset of pan." error:
Implementing both drag and zoom-in with [onScaleUpdate] in [GestureDetector] widget:
onScaleUpdate: (scaleInfo) {
//for drag, use [scaleInfo.focalPointDelta.dx] and [scaleInfo.focalPointDelta.dy]
_controller.translate(scaleInfo.focalPointDelta.dx, scaleInfo.focalPointDelta.dy);
//for zooming use [scaleInfo.scale] and don't react when zoom is exactly '1' [scaleInfo.scale != 1]
if (scaleInfo.scale > 0.5 && scaleInfo.scale < 2 && scaleInfo.scale != 1) {
setState(() {
currentSize = Size(widget.size.width * scaleInfo.scale, widget.size.height * scaleInfo.scale);
});
}
},