Flutter自定义标记插件custom_marker的使用

Flutter自定义标记插件custom_marker的使用

概述

custom_marker 是一个Flutter插件,用于将Widget、本地图片、网络图片或SVG文件转换为 BitmapDescriptor,以便在 google_maps_flutter 中作为图标标记使用。

Example Image

入门指南

添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  custom_marker: ^1.0.0

使用示例

从网络图片创建圆形带边框的标记图标

onPressed: () async {
  markers.add(
    Marker(
      icon: await MarkerIcon.downloadResizePictureCircle(
        'https://thegpscoordinates.net/photos/la/tehran_iran_5u679ezi8f.jpg',
        size: 150,
        addBorder: true,
        borderColor: Colors.white,
        borderSize: 15,
      ),
      position: LatLng(35.6892, 51.3890),
    ),
  );
}

注意事项

  1. 异步函数:你必须在一个异步函数中添加你的标记。
  2. 其他函数:除了将Widget转换为标记外,所有其他函数的使用方式都相同。

将Widget转换为标记

MyMap 类包含Google地图组件

import 'package:custom_marker/marker_icon.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MyMap extends StatefulWidget {
  const MyMap({Key? key}) : super(key: key);

  @override
  _MyMapState createState() => _MyMapState();
}

class _MyMapState extends State<MyMap> {
  Set<Marker> _markers = <Marker>{};
  final GlobalKey globalKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Scaffold(
          body: Stack(
            children: [
              MyMarker(globalKey),
              Positioned.fill(
                child: GoogleMap(
                  initialCameraPosition: CameraPosition(
                      target: LatLng(32.4279, 53.6880), zoom: 15),
                  markers: _markers,
                ),
              ),
            ],
          ),
          floatingActionButton: FloatingActionButton.extended(
            label: FittedBox(child: Text('Add Markers')),
            onPressed: () async {
              _markers.add(
                Marker(
                  markerId: MarkerId('circleCanvasWithText'),
                  icon: await MarkerIcon.widgetToIcon(globalKey),
                  position: LatLng(35.8400, 50.9391),
                ),
              );
              setState(() {});
            },
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        ),
      ],
    );
  }
}

MyMarker 类包含要转换为标记图标的Widget

class MyMarker extends StatelessWidget {
  MyMarker(this.globalKeyMyWidget);
  final GlobalKey globalKeyMyWidget;

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: globalKeyMyWidget,
      child: Stack(
        alignment: Alignment.center,
        children: [
          Container(
            width: 250,
            height: 180,
            decoration: BoxDecoration(color: Colors.black, shape: BoxShape.circle),
          ),
          Container(
            width: 220,
            height: 150,
            decoration: BoxDecoration(color: Colors.amber, shape: BoxShape.circle),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(
                  Icons.accessibility,
                  color: Colors.white,
                  size: 35,
                ),
                Text(
                  'Widget',
                  style: TextStyle(color: Colors.white, fontSize: 25),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

现在我们有了自定义Widget的标记

Custom Widget Marker

函数列表

  • widgetToMarker:从自定义Widget生成图标标记。
  • svgAsset:从资产文件夹中的SVG文件生成图标标记。
  • pictureAsset:从资产文件夹中的图片文件生成图标标记。
  • pictureAssetWithCenterText:从资产文件夹中的图片文件生成带有中心文本的图标标记。
  • circleCanvasWithText:生成带有中心文本的圆形画布图标标记。
  • downloadResizePicture:从互联网下载并调整大小的图片文件生成图标标记。
  • downloadResizePictureCircle:从互联网下载并调整大小的圆形图片文件生成图标标记,并可添加边框。

完整示例代码

import 'package:custom_marker/marker_icon.dart';
import 'package:flutter/rendering.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

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

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Set<Marker> _markers = <Marker>{};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        initialCameraPosition: CameraPosition(target: LatLng(32.4279, 53.6880), zoom: 15),
        markers: _markers,
      ),
      floatingActionButton: FloatingActionButton.extended(
        label: FittedBox(child: Text('Add Markers')),
        onPressed: () async {
          _markers.add(
            Marker(
              markerId: MarkerId('svgAsset'),
              icon: await MarkerIcon.svgAsset(assetName: 'assets/car.svg', context: context, size: 50),
              position: LatLng(35.8400, 50.9391),
            ),
          );

          _markers.add(
            Marker(
              markerId: MarkerId('downloadResizePicture'),
              icon: await MarkerIcon.downloadResizePicture(
                  url: 'https://thegpscoordinates.net/photos/la/tehran_iran_5u679ezi8f.jpg', imageSize: 150),
              position: LatLng(35.6892, 51.3890),
            ),
          );

          _markers.add(
            Marker(
              markerId: MarkerId('downloadResizePictureCircle'),
              icon: await MarkerIcon.downloadResizePictureCircle(
                  'https://thegpscoordinates.net/photos/la/tehran_iran_5u679ezi8f.jpg',
                  size: 150,
                  addBorder: true,
                  borderColor: Colors.white,
                  borderSize: 15),
              position: LatLng(34.6416, 50.8746),
            ),
          );

          setState(() {});
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

希望这些信息对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter自定义标记插件custom_marker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


在Flutter中,自定义标记插件custom_marker通常用于地图应用,比如Google Maps或Flutter Map,以便在地图上显示自定义的标记图标或其他视图。下面是一个示例,展示如何在Flutter应用中使用custom_marker(假设有一个这样的插件,尽管实际上Flutter社区中可能没有直接名为custom_marker的广泛使用的插件,但原理相似,这里我们将模拟一个自定义标记的实现)。

由于custom_marker可能不是一个实际存在的广泛使用的Flutter插件名称,这里我将以Flutter Map和自定义Widget作为标记为例来展示如何实现类似功能。

1. 添加依赖

首先,确保你的pubspec.yaml文件中包含了Flutter Map的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_map: ^0.14.0  # 请检查最新版本号

2. 创建自定义标记Widget

创建一个自定义的标记Widget,比如一个带有图标和文本的标记:

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';

class CustomMarker extends StatelessWidget {
  final LatLng position;
  final String title;

  CustomMarker({required this.position, required this.title});

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.longitude,
      top: position.latitude,
      child: Container(
        width: 80,
        height: 80,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: Colors.blue.withOpacity(0.7),
        ),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(Icons.location_on, color: Colors.white),
              SizedBox(height: 4),
              Text(title, style: TextStyle(color: Colors.white)),
            ],
          ),
        ),
      ),
    );
  }
}

注意:这里的lefttop属性用于定位标记,但在真实应用中,Flutter Map使用转换系统将经纬度转换为屏幕坐标。这里仅为示例,实际使用时需要相应调整。

3. 在Flutter Map中使用自定义标记

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong2.dart';
import 'custom_marker.dart';  // 导入自定义标记

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Map with Custom Marker'),
        ),
        body: FlutterMap(
          options: MapOptions(
            center: LatLng(51.5, -0.09),
            zoom: 13.0,
          ),
          layers: [
            TileLayerOptions(
              urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
              subdomains: ['a', 'b', 'c'],
            ),
            MarkerLayerOptions(
              markers: [
                Marker(
                  width: 80.0,
                  height: 80.0,
                  point: LatLng(51.5, -0.09),
                  builder: (ctx) => CustomMarker(position: LatLng(51.5, -0.09), title: 'London'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

注意MarkerLayerOptionsMarker并不直接支持自定义Widget作为标记。上面的代码是一个概念性的示例。在实际应用中,你可能需要创建一个自定义的MarkerLayer或使用其他方法来在地图上渲染自定义Widget。

由于Flutter Map没有直接支持将Widget作为标记,你可能需要查看flutter_map的扩展包,如flutter_map_marker_clusterflutter_map_marker_popup,或者自己实现一个自定义的Layer来渲染Widget标记。

结论

虽然没有一个直接名为custom_marker的广泛使用的Flutter插件,但你可以通过创建自定义Widget并使用Flutter Map的扩展功能或自定义Layer来实现类似的功能。上面的代码提供了一个基本的概念框架,你可能需要根据实际需求进行调整和扩展。

回到顶部