Карта Google во Флаттере не отвечает на сенсорные события

У меня есть два разных экрана в приложении Flutter, которые используют Google Map (предоставляется этой библиотекой).

Структура виджета для первого

Скаффолд -> ListView -> Видимость -> Центр -> SizedBox -> GoogleMap

и для второго экрана это

Леса -> Контейнер -> Столбец -> SizedBox -> GoogleMap

На обоих экранах я получил одинаковые настройки карты, но по какой-то причине на первом экране карта не реагирует на сенсорные события.

8 ответов

Решение

Вы должны сказать GoogleMap виджет, на какие жесты вы хотите, чтобы он реагировал, установив gestureRecognizers свойство, как-то так:

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

...

GoogleMap(
  initialCameraPosition: CameraPosition(
    target: LatLng(0, 0),
  ),
  gestureRecognizers: Set()
    ..add(Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
);

Это не относится к GoogleMap виджет, вам нужно будет сделать это с любым виджетом, который использует AndroidView/UIKitView под крышками для управления жестами, когда он находится внутри прокручиваемого вида.

У меня была та же проблема, и после долгих поисков я нашел следующее решение, так что оно будет работать:

GoogleMap(
   gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>[
      new Factory<OneSequenceGestureRecognizer>(() => new EagerGestureRecognizer(),),
   ].toSet(),)

Причина в том, что EagerGestureRecognizer это распознаватель жестов, который охотно заявляет о победе во всех сферах жестов.

Ссылка:

Управление приоритетом жестов между двумя виджетами

propriedade жест

Я думаю, это зависит от того, какие жесты поддерживает ваш родительский виджет.

Этот способ работает для меня. Моя карта в TabBarView > ListView > GoogleMap

 GoogleMap(
      gestureRecognizers: Set()
        ..add(Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
        ..add(Factory<ScaleGestureRecognizer>(() => ScaleGestureRecognizer()))
        ..add(Factory<TapGestureRecognizer>(() => TapGestureRecognizer()))
        ..add(Factory<VerticalDragGestureRecognizer>(
            () => VerticalDragGestureRecognizer())),

У меня похожая проблема, но в моем случае карта находится внутри списка (на самом деле SliverPersistentHeader). Добавление жеста панорамирования сработало, но я все еще не могу прокрутить карту по вертикали. Поэтому я также добавил VerticalDragGestureRecognizer и это сработало, как и ожидалось.

GoogleMap(
    gestureRecognizers: Set()
      ..add(Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
      ..add(Factory<VerticalDragGestureRecognizer>(
          () => VerticalDragGestureRecognizer())),
    // rest code
),

Примечание. Вы также можете добавить еще один gestRecognizer, например: ScaleGestureRecognizer,

Оберните детектором жестов и добавьте onVerticalStart

      GestureDetector(
    onVerticalDragStart: (start) {},
    child: GoogleMap(
      gestureRecognizers: Set()
        ..add(Factory<OneSequenceGestureRecognizer>(
            () => new EagerGestureRecognizer()))
        ..add(Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
        ..add(
            Factory<ScaleGestureRecognizer>(() => ScaleGestureRecognizer()))
        ..add(Factory<TapGestureRecognizer>(() => TapGestureRecognizer()))
        ..add(Factory<VerticalDragGestureRecognizer>(
            () => VerticalDragGestureRecognizer())),

      onMapCreated: (GoogleMapController c) {
        _controller.complete(c);
      },
      initialCameraPosition: CameraPosition(
        target: LatLng(9.856326, 78.285448),
        zoom: 10.4746,
      ),
      mapType: MapType.normal,
      
    ),
  ),

]1}

Глядя на структуру виджета для первого экрана, я думаю, что проблема в том, что ListView который используется прокручивается. Благодаря этому все сенсорные события распространяются на ListView вместо карты.

Можете ли вы попробовать добавить physics параметр для ListView? Вы можете попробовать добавить

ListView(
  physics: NeverScrollableScrollPhysics(),
  /*Rest of the ListView implementation*/
)

Обновление: рабочий пример

 return Scaffold(
    body: ListView(
      itemExtent: MediaQuery.of(context).size.height*1.2,
      children: <Widget>[
        Column(
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            buildMap(), /*The map function*/
            Container(
               /*Any other child widget*/
            )
          ],
        ),
        /*Any other child widgets in the List*/
      ],
    )
  );

Примечание. Вам нужно начать прокрутку в горизонтальном направлении, чтобы прокрутка карты работала, поскольку в случае вертикальной прокрутки она по умолчанию будет использовать ListView.

Для последнего решения этой проблемы.

Я также нашел альтернативный и рефакторинговый код, который, как мне кажется, более читабелен и чище, чем я нашел из этого источника (https://api.flutter.dev/flutter/widgets/PlatformViewSurface/gestureRecognizers.html), и он также работает на том же уровне. время.

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

GoogleMap(
...
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
        Factory<OneSequenceGestureRecognizer>(
          () => EagerGestureRecognizer(),
        ),
      },
...
)

Как указано в источнике,

EagerGestureRecognizer — это специальный распознаватель жестов, который сразу же запрашивает жест после события «указатель вниз».

Таким образом, основным ключевым игроком в этом является EagerGestureRecognizer.

Имейте в виду, что google_maps_flutter предварительный просмотр разработчика, версия 0.2. Пожалуйста, будьте терпеливы для дополнительных функций, которые будут добавлены.

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