Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid scrolling listview when scrolling in map within listview

I have a ListView, at the top of which I have a map, I want the map to scroll out of view when the ListView is scrolled, but I also want the user to be able to interact with the map. So scrolling should only happen when the user scrolls on the other ListView widgets and not when they scroll on the map, then I want the gesture to be applied directly to the map. Currently though, when the user scrolls on the map, it scrolls the whole ListView.

I have tried the other suggestion that I have come across on here In Flutter, how can a child widget prevent the scrolling of its scrollable parent? I added a GestureDetector as suggested in the answer to the post above wrapping the map container in the sample below, however this just blocked scrolling of both the ListView and the Map when scrolling on the map. Video link https://imgur.com/SeCRzUC

Here is the widget that is returned by my build method. This code depends on the google_maps_flutter plugin.

Container(
  height: MediaQuery.of(context).size.height,
  child:
  ListView.builder(
    itemCount: 12 + 1,
    itemBuilder: (context, index) {
      if (index == 0) return GestureDetector(
        onVerticalDragUpdate: (_){},
        child: Container(
          height: MediaQuery.of(context).size.height / 2,
          child: GoogleMap(initialCameraPosition: initalPosition),
        ),
      );
      else return ListTile(title: Text("$index"),);
    }
  )
),

I had hoped the map would capture gestures but it doesn't, the listview which contains it captures all. Could anyone suggest how I could force all gestures for this item in the list to be passed directly to the map, and still have the list scroll when other items in the list are scrolled?

like image 403
diarmuid Avatar asked May 18 '19 08:05

diarmuid


People also ask

How do I make my ListView builder not scrollable?

How do I make my ListView builder not scrollable? You can make the ListView widget never scrollable by setting physics property to NeverScrollableScrollPhysics().

What is the difference between SingleChildScrollView and ListView?

SingleChildScrollView behaves the same as ListView, but it is best when using different Widgets with different Sizes, just in need of scrolling behavior.

How do you make list view not scrollable in flutter?

How do you make list view not scrollable in flutter? Flutter ListView – Never Scrollable You can make the ListView widget never scrollable by setting physics property to NeverScrollableScrollPhysics().

How do I scroll to a specific position in ListView flutter?

There is always a problem with scrolling in ListView inside Flutter, so here I am coming with an example where we can scroll to a specific index of ListView. Here we are using scroll_to_index dependency which solves our equation of scrolling easily.


2 Answers

The accepted answer (Eset Mehmet's answer was marked as excepted as of time of writing) is way to complicated and in my case it did not even work! It provided left-to-right scrolling, panning, and scaling, however top-to-bottom scrolling still scrolled the ListView.

A real solution is very simple, since GoogleMap by default has those gesture detectors. You must just specify that gesture detection must be prioritized by GoogleMap and not ListView. This is achieved by giving GoogleMap object an EagerGestureRecognizer in the following way for example.

ListView(
  children: <Widget>[
    Text('a'),
    Text('b'),
    GoogleMap(
      ...,
      gestureRecognizers: {
        Factory<OneSequenceGestureRecognizer>(
          () => EagerGestureRecognizer(),
        ),
      },
    ),
  ],
)

In this way, all gestures that happen on or over the GoogleMap object will be prioritized by GoogleMap instead of any other widget.

like image 128
campovski Avatar answered Sep 23 '22 11:09

campovski


Edit: campovski 's answer down below is the updated answer.

Depreciated Answer:

  • Wrap everything with ListView if you want to move out GoogleMap widget from the screen when scrolling.

  • Override ListView scrolling phyics with GoogleMap gestureRecognizers.

  • Disable ListView.builder scrolling physics due to conflict between ListView physics.

First import the dependencies:

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';

build method:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: <Widget>[
          SizedBox(
            height: MediaQuery.of(context).size.height / 2,
            child: GoogleMap(
              initialCameraPosition:
                  CameraPosition(target: LatLng(41, 29), zoom: 10),
              gestureRecognizers: Set()
                ..add(
                    Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
                ..add(
                  Factory<VerticalDragGestureRecognizer>(
                      () => VerticalDragGestureRecognizer()),
                )
                ..add(
                  Factory<HorizontalDragGestureRecognizer>(
                      () => HorizontalDragGestureRecognizer()),
                )
                ..add(
                  Factory<ScaleGestureRecognizer>(
                      () => ScaleGestureRecognizer()),
                ),
            ),
          ),
          ListView.builder(
            physics: const NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            itemCount: 12,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text("$index"),
              );
            },
          )
        ],
      ),
    );
  }
like image 43
Esen Mehmet Avatar answered Sep 23 '22 11:09

Esen Mehmet