flutterflutter-listviewgesturedetector

onVerticalDragUpdate and onPanUpdate of GestureDetector does not get called with a ListView as child of GestureDetector Flutter


I want to develop an app where I use a TabBar that consists of two screens. In the first screen, I have a ListView. I want the TabBar to be hidden when the ListView is scrolled down, and to be shown back when the ListView is scrolled up. I used GestureDetector as the parent of ListView to detect that the user scrolled up and/or down. By searching online, I found that using onVerticalDragUpdate and onPanUpdate can detect up and down vertical scroll. But now the problem is that these methods are not called! Other methods of GestureDetector such as onTap are called. I think the reason is that the ListView absorbs the vertical scroll. So what is the solution for this? Your help is strongly appreciated!!

Note: Using SliverAppBar does not match my requirements well.

Here is my code:

SafeArea(
        child: Stack(
          children: [
            TabBarView(
              controller: _controller,
              children: [
                GestureDetector(
                  onTap: () {
                    print('onTap called!');
                  },
                  onVerticalDragUpdate: (updates) {
                    print('onVerticalDragUpdate is called!');
                  },
                  onPanUpdate: (update) {
                    print('onPanUpdate is called!');
                  },
                  child: ListView.builder(
                    itemCount: 20,
                    itemBuilder: (ctx, index) => Card(
                      child: ListTile(
                        title: Text('Hi there! $index'),
                      ),
                    ),
                  ),
                ),
                Container(color: Colors.purpleAccent),
              ],
            ),
            Align(
              alignment: Alignment.topCenter,
              child: TabBar(
                controller: _controller,
                labelColor: Colors.black,
                indicator: UnderlineTabIndicator(
                  borderRadius: BorderRadius.circular(8),
                  borderSide: const BorderSide(
                    color: Colors.black,
                    width: 2,
                  ),
                  insets: const EdgeInsets.symmetric(horizontal: -8),
                ),
                indicatorSize: TabBarIndicatorSize.label,
                isScrollable: true,
                tabs: const [
                  Tab(
                    text: 'Social',
                    height: 36,
                  ),
                  Tab(
                    icon: Text('Videos'),
                    height: 36,
                  ),
                ],
              ),
            ),
          ],
        ),
      )

And here is the output:

enter image description here


Solution

  • try this

    NotificationListener<ScrollNotification>(
       onNotification: (scrollNotification) {
           if (scrollNotification is UserScrollNotification) {
               ....
           }
           
           return false;
       },
       child: ... }
    

    or choose another type of ScrollNotification if UserScrollNotification doesn't fit to you