以编程方式 Select 导航至位置的标记 Google_Maps_Flutter

Programmatically Select Marker to Navigate To Location Google_Maps_Flutter

我正在尝试开发一种用户体验,向用户提供前往的地点列表,并且在select访问其中一个地点后,我希望它

  1. 在地图上添加标记
  2. 显示信息window
  3. 提供导航至 位置。

我能够使用信息 from this PR(似乎没有官方文档)从这里开始:

为此:

但是,显示标记信息仍然不会使给定标记“激活”。当我 select 标记时,插件的功能实际上会显示用于导航到右下角给定位置的选项,如下所示:

我想要的是 select 列表底部的场地离子按一次自动显示第三张图片中的所有三个标准。即再次:

  1. 位置标记
  2. 信息window
  3. 导航到该位置的选项。

现在,用户必须单击底部列表中的条目,然后相当不直观地 单击地图上的标记 才能使用导航选项出现。

我将如何以编程方式启动当用户在 select 从列表中“点击”标记时发生的“点击”事件?

这是我当前用于更改视口、添加标记和显示信息的代码 window:

Future<void> goSomewhere(id, name, distance, address, lat, lng) async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(
    CameraPosition(target: LatLng(lat, lng), zoom: 14.0)));
setState(() {
  _markers.add(Marker(
    markerId: MarkerId(id),
    position: LatLng(lat, lng),
    infoWindow: InfoWindow(
      title: name,
      snippet: address,
    ),
    onTap: () {
      //_pageController.jumpToPage(i);
    },
    icon: BitmapDescriptor.defaultMarker,
  ));
  print(MarkerId(id));
  controller.showMarkerInfoWindow(MarkerId(id));
});

}

现在,我的解决方案确实添加了标记并显示了信息 window,但很快就给用户提供了导航到该位置的选项 ,除非 用户单击标记。在目前的状态下,我构建了一些可以提供非常次优的用户体验的东西。

我已经尝试过 highlighting the marker 等替代解决方案,但它并不完全具备我正在寻找的功能。我不明白插件中发生了什么事件,“selects”标记点击,我发现所有尝试“以编程方式”select 标记做了一些版本的突出显示。简单地说明在单击标记时在哪里查看正在启动的事件会有所帮助。

我没有得出完整的答案,但我想分享我的经验,以防其他人遇到这个问题并感到困惑。通过浏览 Flutter Github / 在论坛中询问,我得到了三个关键要点:

  1. 据我所知,Flutter中没有办法模拟marker的“敲击”。我尝试查看 the Kotlin/Swift APIs for platform channels 来自己编写其中的一些功能,但老实说,它离我的驾驶室还很远,我为此浪费了很多时间。这也可能导致必须与 Google 的好人一起完成批准程序才能接受我的更改,但我个人现在还没有时间。

  2. 我发现了一个名为 Maps Launcher 的包,Craig 在评论部分也提到了它,它能够通过两种方法启动地图应用程序 - 通过查询启动和通过以下方式启动Latitude/Longitude。此功能实际上与点击标记然后点击右下角的两个地图选项之一 select 时获得的功能相同。

  3. 我发现两者的主要区别 点击标记时获得的图标是一个启动 方向查询,另一个方向经纬度 - 只是 比如 Maps Launcher 插件。

因此,根据这三个信息,我重新设计了应用程序:

看起来像这样:

现在是用户:

  1. 从列表中选择一个位置。
  2. 选择新位置会添加一个标记并显示该位置的信息窗口
  3. 可以点击右边的按钮导航到指定位置。

在我看来,这种体验要干净得多 - 在 select 标记时,您可以启动的两个地图选项(通过查询与 lat/long)之间没有歧义,因为启动地图图标的按钮现在位于列表视图上。这也使您可以很容易地导航到每个标记,只需在列表视图中单击它,然后通过按右侧的按钮决定是否需要导航方向。

将此添加到您的应用程序的代码非常简单:

new Flexible(
            child: ListView.builder(
            itemCount: venues.length,
            padding: EdgeInsets.all(4.0),
            itemBuilder: (context, index) {
              return Card(
                  color: _selectedIndex != null && _selectedIndex == index
                      ? Colors.greenAccent
                      : Colors.white,
                  child: ListTile(
                onTap: () {
                  goSomewhere(
                      venues[index].venueId,
                      venues[index].name,
                      venues[index].distance,
                      venues[index].formattedAddress,
                      double.parse(venues[index].latitude),
                      double.parse(venues[index].longitude)
                  );
                  _onSelected(index);
                },
                title: Text(
                  venues[index]
                      .name /*+ ' and ' + venues[index].formattedAddress*/,
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
                trailing: Container(
                    child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    primary: Colors.blue,

                  ),
                      onPressed: () => MapsLauncher.launchQuery(
                          venues[index].formattedAddress),
                      child: Icon(Icons.assistant_navigation),
                )),
                subtitle: Text(venues[index].formattedAddress),
              ));
            },
          ))

这是一个细微的差别,但我做了一些测试,我的(小)用户群似乎更喜欢这个,因为它更直观。此外,无论他们按哪个按钮,他们在地图应用程序中获得的位置都有一个可识别的地址。

虽然这不是对原始问题的“完整”回答,但我希望这可以帮助那些在 Flutter 之旅中坚持使用该框架的人——尽管存在一些早期障碍。

你赢了我!我之前正要回答这个问题,但是当我重新加载页面时,我看到你已经回答了。虽然看起来您已经找到了问题的解决方案,但我还是想在这里发布我的答案。请看下面:

我找不到以编程方式显示地图工具栏的方法(用于导航到右下角给定位置的选项),因为您确实需要单击标记才能显示它。但这是我认为适合您的用例的解决方法:

  1. 通过在 GoogleMap() 小部件中设置 mapToolbarEnabled: false 来禁用地图工具栏。 (无论如何,地图工具栏仅适用于 Android)
  2. 创建自定义地图工具栏,从应用程序启动 Google Maps and Directions URL。该工具栏仅在您 select 列表视图中的位置或单击标记时显示。

我使用 url_launcher 包来启动 Google 地图和路线 URL。

 Future<void> _launchUrl(bool isDir, double lat, double lon) async {
    String url = 'https://www.google.com/maps/search/?api=1&query=$lat,$lon';

    if (isDir) {
      url = 'https://www.google.com/maps/dir/?api=1&origin=Googleplex&destination=$lat,$lon';
    }

    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }

然后我在自定义地图工具栏小部件上使用了上述方法

Widget mapToolBar() {
    return Row(
      children: [
        FloatingActionButton(
          child: Icon(Icons.map),
          backgroundColor: Colors.blue,
          onPressed: () {
            _launchUrl(false, {your_lat}, {your_lng})
          },
        ),
        FloatingActionButton(
          child: Icon(Icons.directions),
          backgroundColor: Colors.blue,
          onPressed: () {
            _launchUrl(true, {your_lat}, {your_lng};
          },
        ),
      ],
    );
  }

然后将自定义小部件与 Googlemap() 小部件

放在 Stack 小部件中
Widget build(BuildContext context) {
    return Scaffold(
      body: Column(children: <Widget>[
        Expanded(
          flex: 7,
          child: Stack(children: [
            GoogleMap(
                  .
                  .
                  .
              ),
            mapToolBar()
          ]),
        ),
        _pageViewBuilder(context),
      ]),
    );
  }