Как избежать прокрутки списка при прокрутке карты в списке

У меня есть ListView, в верхней части которого у меня есть карта, я хочу, чтобы карта прокручивалась вне поля зрения при прокрутке ListView, но я также хочу, чтобы пользователь мог взаимодействовать с картой. Таким образом, прокрутка должна происходить только тогда, когда пользователь прокручивает другие виджеты ListView, а не когда они прокручивают карту, тогда я хочу, чтобы жест применялся непосредственно к карте. Однако в настоящее время, когда пользователь прокручивает карту, он прокручивает весь ListView.

Я пробовал другое предложение, с которым я столкнулся здесь Как во Flutter дочерний виджет может предотвратить прокрутку своего родителя с возможностью прокрутки? Я добавил GestureDetector, как было предложено в ответе на пост выше, обернув контейнер карты в примере ниже, однако это просто заблокировало прокрутку как ListView, так и карты при прокрутке на карте. Ссылка на видео https://imgur.com/SeCRzUC

Вот виджет, возвращаемый моим методом сборки. Этот код зависит от плагина google_maps_flutter.

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"),);
    }
  )
),

Я надеялся, что карта будет фиксировать жесты, но это не так, список, содержащий ее, фиксирует все. Может ли кто-нибудь предложить, как я могу заставить все жесты для этого элемента в списке передаваться непосредственно на карту и при этом прокручивать список, когда прокручиваются другие элементы в списке?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
3 922
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обновлено: ответ Камповски внизу является обновленным ответом.

Depreciated Answer:

  • Оберните все с помощью ListView, если вы хотите убрать виджет GoogleMap с экрана при прокрутке.

  • Переопределите физику прокрутки ListView с помощью GoogleMap GesRecognizers.

  • Отключить физику прокрутки ListView.builder из-за конфликта между физикой ListView.

Сначала импортируйте зависимости:

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

метод сборки:

  @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"),
              );
            },
          )
        ],
      ),
    );
  }

Спасибо за ответ! Правильно ли я говорю, что теперь ListView вообще не будет прокручиваться? Извините, перечитав свой первоначальный пост, я понимаю, что не дал понять, что я все еще хочу, чтобы ListView прокручивался, если пользователь прокручивает любую другую часть списка (кроме карты)

diarmuid 18.05.2019 13:53

@diarmuid это именно то, что тебе нужно, попробуй :)

Esen Mehmet 18.05.2019 13:55
Ответ принят как подходящий

Принятый ответ (ответ Эсет Мехмет был помечен как исключенный на момент написания) слишком сложен, и в моем случае он даже не сработал! Он обеспечивал прокрутку слева направо, панорамирование и масштабирование, однако прокрутка сверху вниз по-прежнему прокручивала ListView.

Реальное решение очень простое, так как GoogleMap по умолчанию имеет эти детекторы жестов. Вы должны просто указать, что обнаружение жестов должно иметь приоритет GoogleMap, а не ListView. Это достигается путем предоставления GoogleMap объекту EagerGestureRecognizer, например, следующим образом.

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

Таким образом, все жесты, которые выполняются на объекте GoogleMap или над ним, будут иметь приоритет для GoogleMap, а не для любого другого виджета.

Спасибо @campovski, это 5-строчное решение отлично работает для меня. Я могу прокручивать ListView, а затем я могу прокручивать карту, когда касаюсь карты.

xilex 05.07.2020 04:55

@eluong Рад, что это помогло, для меня это был кошмар, поэтому я решил поделиться своим решением.

campovski 05.07.2020 19:36

@campovski Спасибо! Это то, что я искал

Yunus Kulyyev 20.08.2020 00:21

Нет необходимости в EagerGestureRecognizer, попробуйте это решение stackoverflow.com/questions/54280541/… С этим решением вы по-прежнему можете использовать просмотр страниц. Распознаватель Eager не разрешает прокрутку просмотра страниц

giorgio79 28.01.2021 17:08

Другие вопросы по теме