How to show a widget only when user is scrolling?
You are right, there aren't any onScroll
events on GestureDetector
, but there are onVerticalDrag
events, which are basically the same, with another name.
But, for that, you don't actually need a GestureDetector
. You can listen to the scroll changes, handling the ScrollStartNotification
and ScrollEndNotification
notifications with a NotificationListener
, since you are already using a SingleChildScrollView
.
I've created a little example to show you that which will produce the following:
On scroll a flag to display the button is set to true
and at the end, it will reset back to false
and rebuild the tree with no button after 5 seconds if no more scroll notifications come in between (that's the reason why you don't set the _buttonShowing = false
after the Future
completes but before.
bool _buttonShowing = false;
@override
Widget build(BuildContext context) {
List<Widget> columnWidgets = List<Widget>.filled(100, Container(height: 100.0, child: Placeholder()));
if (_buttonShowing) {
columnWidgets = List.from(columnWidgets)
..insert(
3, Visibility(child: RaisedButton(child: Text('Press me'), onPressed: () {}), visible: _buttonShowing));
}
return Scaffold(
appBar: AppBar(),
body: NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollStartNotification) {
if (!_buttonShowing) {
setState(() => _buttonShowing = true);
}
} else if (scrollNotification is ScrollEndNotification) {
if (_buttonShowing) {
_buttonShowing = false;
Future.delayed(Duration(seconds: 5)).then((_) => setState(() {}));
}
}
},
child: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: columnWidgets),
),
),
);
}
mirkancal
Software Engineer from Kyiv, Ukraine. Working professionally with Flutter for three years, started during my senior project, when Flutter was Alpha.
Updated on December 09, 2022Comments
-
mirkancal over 1 year
I want to hide buttons on screen and show them after user starts scrolling till for the 5 seconds from the last scroll.
I've wrapped my
SingleChildScrollView
withGestureDetector
and change the visibility value fromonTap
callback to hide my buttons withVisibility
widget. However, there is no event like onScroll onGestureDetector
.Is there anyone who succesfully implement that effect or is there any built-in animation for what I'm trying to achieve?
-
mirkancal about 5 yearsThank you for your help, those properties seems to will work. However it locks my UI if I wrap GestureDetector with SingleChildScrollView, like in your example, and If I wrap my SingleChildScrollView with GestureDetector, nothing happens.
-
Miguel Ruivo about 5 yearsActually you don't need a
GestureDetector
for that. By using only aSingleChildScrollView
and aNotificationListener
to handle the notifications that you need (start and end) you should be fine. I've edited my answer accordingly and provided a little example. -
mirkancal about 5 yearsIts working but when there are not enough items to scroll, the buttons don't show up. I guess it doesn't render SingleChildScrollView if it isn't needed. And when there is enough items to scroll, the buttons show only for once. Any idea?
-
Miguel Ruivo about 5 years
SingleChildScrollView
won't scroll if you actually don't need a scroll. You shouldn't expect a user to start scrolling if the screen is already displaying all of its content so you shouldn't rely on scroll to display the button for that scenario IMO. -
mirkancal about 5 yearsThank you, I think I have to find another solution.