Flutter自定义信息窗口插件custom_info_window的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter自定义信息窗口插件custom_info_window的使用

Custom Info Window 是一个基于Flutter Widget的自定义信息窗口,专为 google_maps_flutter 插件设计。它允许开发者在地图上添加自定义样式的信息窗口,以增强用户体验。

示例展示

上述GIF展示了如何通过点击地图上的标记来显示和隐藏自定义信息窗口。

完整示例代码

依赖安装

首先,在您的 pubspec.yaml 文件中添加 custom_info_windowgoogle_maps_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  custom_info_window: ^latest_version
  google_maps_flutter: ^latest_version

请将 ^latest_version 替换为实际的最新版本号。

示例代码

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:custom_info_window/custom_info_window.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CustomInfoWindowExample(),
    );
  }
}

class CustomInfoWindowExample extends StatefulWidget {
  @override
  _CustomInfoWindowExampleState createState() => _CustomInfoWindowExampleState();
}

class _CustomInfoWindowExampleState extends State<CustomInfoWindowExample> {
  CustomInfoWindowController _customInfoWindowController = CustomInfoWindowController();

  final LatLng _latLng = LatLng(28.7041, 77.1025); // Example coordinates (Delhi)
  final double _zoom = 15.0;

  Set<Marker> _markers = {};

  @override
  void dispose() {
    _customInfoWindowController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Adding a marker to the map with an onTap event that shows the info window.
    _markers.add(
      Marker(
        markerId: MarkerId("marker_id"),
        position: _latLng,
        onTap: () {
          _customInfoWindowController.addInfoWindow(
            Column(
              children: [
                Expanded(
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.blue,
                      borderRadius: BorderRadius.circular(4),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            Icons.account_circle,
                            color: Colors.white,
                            size: 30,
                          ),
                          SizedBox(width: 8.0),
                          Text(
                            "I am here",
                            style: Theme.of(context).textTheme.headline6?.copyWith(color: Colors.white),
                          )
                        ],
                      ),
                    ),
                    width: double.infinity,
                    height: double.infinity,
                  ),
                ),
                Triangle.isosceles(
                  edge: Edge.BOTTOM,
                  child: Container(
                    color: Colors.blue,
                    width: 20.0,
                    height: 10.0,
                  ),
                ),
              ],
            ),
            _latLng,
          );
        },
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Info Window Example'),
        backgroundColor: Colors.red,
      ),
      body: Stack(
        children: <Widget>[
          GoogleMap(
            onTap: (position) {
              _customInfoWindowController.hideInfoWindow();
            },
            onCameraMove: (position) {
              _customInfoWindowController.onCameraMove();
            },
            onMapCreated: (GoogleMapController controller) async {
              _customInfoWindowController.googleMapController = controller;
            },
            markers: _markers,
            initialCameraPosition: CameraPosition(
              target: _latLng,
              zoom: _zoom,
            ),
          ),
          CustomInfoWindow(
            controller: _customInfoWindowController,
            height: 75,
            width: 150,
            offset: 50,
          ),
        ],
      ),
    );
  }
}

这段代码创建了一个简单的Flutter应用程序,其中包含一个带有自定义信息窗口的地图视图。当用户点击地图上的标记时,会显示一个蓝色背景的自定义信息窗口,并且可以通过点击地图的其他地方来关闭该窗口。

请注意,为了确保最佳兼容性和性能,请始终使用最新的稳定版本的 custom_info_windowgoogle_maps_flutter 插件。


更多关于Flutter自定义信息窗口插件custom_info_window的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义信息窗口插件custom_info_window的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用custom_info_window插件来自定义Google Maps中的信息窗口的示例代码。这个插件允许你使用自定义的Flutter Widget作为Google Maps中的信息窗口。

首先,确保你已经在pubspec.yaml文件中添加了custom_info_windowgoogle_maps_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.1.1  # 请检查最新版本
  custom_info_window: ^1.0.0  # 请检查最新版本

然后,运行flutter pub get来安装这些依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用custom_info_window插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:custom_info_window/custom_info_window.dart';
  1. 定义自定义信息窗口的Widget
class CustomInfoWindow extends StatelessWidget {
  final Marker marker;

  CustomInfoWindow({required this.marker});

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: 4.0,
      child: Container(
        padding: EdgeInsets.all(16.0),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8.0),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.2),
              spreadRadius: 5,
              blurRadius: 7,
              offset: Offset(0, 3), // changes position of shadow
            ),
          ],
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text('Title: ${marker.title}'),
            SizedBox(height: 8.0),
            Text('Snippet: ${marker.snippet}'),
          ],
        ),
      ),
    );
  }
}
  1. 设置Google Maps和自定义信息窗口
class MapsScreen extends StatefulWidget {
  @override
  _MapsScreenState createState() => _MapsScreenState();
}

class _MapsScreenState extends State<MapsScreen> {
  late GoogleMapController _controller;
  late Set<Marker> _markers = HashSet<Marker>();
  late Map<Marker, CustomInfoWindow> _customInfoWindows = {};

  @override
  void initState() {
    super.initState();
    _markers.add(
      Marker(
        markerId: MarkerId('marker_1'),
        position: LatLng(-34, 151),
        infoWindow: InfoWindow(title: 'Sydney', snippet: 'Australia'),
        onTap: () {
          _onMarkerTap(MarkerId('marker_1'));
        },
      ),
    );
  }

  void _onMarkerTap(MarkerId markerId) {
    final Marker? marker = _markers.firstWhereOrNull((m) => m.markerId == markerId);
    if (marker != null) {
      _controller.showInfoWindow(markerId);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Info Window Example'),
      ),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: CameraPosition(
          target: LatLng(-34, 151),
          zoom: 11.0,
        ),
        markers: _markers.toSet(),
        onMapCreated: (GoogleMapController controller) {
          _controller = controller;
          _controller.setInfoWindowAdapter(new CustomInfoWindowAdapter(
            getInfoContents: (MarkerId markerId) {
              final Marker? marker = _markers.firstWhereOrNull((m) => m.markerId == markerId);
              if (marker != null) {
                return CustomInfoWindow(marker: marker);
              }
              return null;
            },
            getAnchor: (MarkerId markerId, RenderBox? markerBox) {
              return markerBox?.localToGlobal(Offset.zero) ?? Offset.zero;
            },
            getInfoWindowPosition: (MarkerId markerId, RenderBox? markerBox) {
              final Size? size = markerBox?.size;
              if (size != null) {
                return Point(
                  size.width / 2 - 20, // Adjust based on your design
                  -size.height - 10, // Adjust based on your design
                );
              }
              return Point(0, 0);
            },
          ));
        },
      ),
    );
  }
}
  1. 运行你的应用

确保你已经正确设置了API密钥,并且你的设备或模拟器可以访问Google Maps服务。然后运行你的Flutter应用,你应该能看到自定义的信息窗口在点击标记时显示。

这个示例展示了如何使用custom_info_window插件来自定义Google Maps中的信息窗口。你可以根据需要进一步自定义CustomInfoWindow Widget的样式和内容。

回到顶部