代码之家  ›  专栏  ›  技术社区  ›  Dimon Buzz

Flitter GoogleMap插件中的自定义标记

  •  1
  • Dimon Buzz  · 技术社区  · 8 年前

    有没有办法向官方展示定制标记 Flutter Google Maps plugin 在地图上?根据文档,找不到任何方法来执行此操作。

    2 回复  |  直到 7 年前
        1
  •  16
  •   Saad Ahmed    6 年前
    BitmapDescriptor customIcon;
    
    // make sure to initialize before map loading
    BitmapDescriptor.fromAssetImage(ImageConfiguration(size: Size(12, 12)),
            'assets/images/car-icon.png')
        .then((d) {
      customIcon = d;
    });
    
    final nearbyCarsLocation = [
      LatLng(24.9286825, 67.0403249),
      LatLng(24.985577, 67.0661056), //24.9294892,67.0391903,18.73z
    ];
    
    void _getNearByCars() {
    
      for (var i = 0; i < nearbyCarsLocation.length; i++) {
        var now = new DateTime.now().millisecondsSinceEpoch;
        _markers.add(Marker(
          markerId: MarkerId(nearbyCarsLocation[i].toString() + now.toString()),
          position: nearbyCarsLocation[i],
          // infoWindow: InfoWindow(title: address, snippet: "go here"),
          icon: customIcon ));
      }
      notifyListeners();
    }
    

    希望这将有助于在附近地区获得海关

        2
  •  7
  •   Franzé Jr.    7 年前

    我正在使用:

    controller.addMarker(MarkerOptions(
      icon: BitmapDescriptor.fromAsset("images/restaurant.png"),
      position: LatLng(40.017870, -105.278350),
    ));
    

    它在Android上运行良好,但在iOS上不起作用。

        3
  •  7
  •   Luca Antonelli    6 年前

    BitmapDescriptor.fromAsset 是 deprecated

    使用 BitmapDescriptor.fromAssetImage

    在选择适当的资产时,它尊重设备DPI。看见 Declaring resolution-aware image assets .

        4
  •  2
  •   kapil singh    7 年前

    根据新插件BitmapDescriptor.fromAsset(“images/restaurant.png”)工作不正常,请参考此 link 找到我的解决办法。

    Future<BitmapDescriptor> _getAssetIcon(BuildContext context) async {
    final Completer<BitmapDescriptor> bitmapIcon =
        Completer<BitmapDescriptor>();
    final ImageConfiguration config = createLocalImageConfiguration(context);
    
    const AssetImage('assets/red_square.png')
        .resolve(config)
        .addListener((ImageInfo image, bool sync) async {
      final ByteData bytes =
          await image.image.toByteData(format: ImageByteFormat.png);
      final BitmapDescriptor bitmap =
          BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
      bitmapIcon.complete(bitmap);
    });
    
    return await bitmapIcon.future;}
    

    像这样使用这个

    void _add(LatLng position,String address) async{
    final MarkerId markerId = MarkerId('1');
    BitmapDescriptor markericon = await _getAssetIcon(context);
    
    // creating a new MARKER
    final Marker marker = Marker(
      markerId: markerId,
      position: position,
      infoWindow: InfoWindow(title: address, snippet: 'go here'),
      icon: markericon
    );
    
    setState(() {
      _markers[markerId] = marker;
    });}
    

    希望它对你有用。

        5
  •  2
  •   Constante de Planck    6 年前

    https://www.youtube.com/watch?v=ajuo0HjN3lY&t=905s

    BitmapDescriptor icon;
    
    
    @override
      void initState() {
        getIcons();
        super.initState();
      }
    
    
    // Cargar imagen del Marker
      getIcons() async {
        var icon = await BitmapDescriptor.fromAssetImage(
            ImageConfiguration(devicePixelRatio: 3.2),
            "assets/images/markeruser.png");
        setState(() {
          this.icon = icon;
        });
      }
    
    
    // Crear Marker
      createMarkers() {
        markers.add(
          Marker(
            markerId: MarkerId("MarkerCurrent"),
            position: currentLocation,
            icon: icon,
            infoWindow: InfoWindow(
                title: "Mi Ubicacion",
                snippet:
                    "Lat ${currentLocation.latitude} - Lng ${currentLocation.longitude}"),
            draggable: true,
            onDragEnd: onDragEnd,
          ),
        );
      }
    
    
        6
  •  1
  •   Navin Kumar    7 年前

    **试试这个,

    _createMarkerImageFromAsset("assets/locationMarker.png");
    
     Future <BitmapDescriptor> _createMarkerImageFromAsset(String iconPath) async {
        ImageConfiguration configuration = ImageConfiguration();
         bitmapImage = await BitmapDescriptor.fromAssetImage(
            configuration,iconPath);
        return bitmapImage;
      }
    

    将bitmapImage设置为标记

     Marker(
            markerId: MarkerId('value'),
            icon: bitmapImage,
            position: LatLng(),
           );
    
        7
  •  1
  •   Arshad    6 年前
    final bitmapIcon = await BitmapDescriptor.fromAssetImage(ImageConfiguration(size: Size(48,48)), 'assets/images/marker.png');
    
    Marker(
            markerId: MarkerId('marker_2'),
            position: LatLng(_position.target.latitude, _position.target.longitude),
            draggable: true,
            icon: bitmapIcon,
          )
    

    尝试上面的代码,使用异步编程。

        8
  •  1
  •   Hector Aguero    6 年前

    实际上,只有 example repository of google_maps 工作…因为颤振sdk在API中有一些变化(我目前在1.8中)

    因此,这就是函数,与kapil answer相同,在API中做了一些更改,您只需要更改图像路由的“assets/red_square.png”行。

       Future<BitmapDescriptor> _getAssetIcon(BuildContext context) async {
       final Completer<BitmapDescriptor> bitmapIcon =
           Completer<BitmapDescriptor>();
       final ImageConfiguration config = createLocalImageConfiguration(context);
    
       const AssetImage('assets/red_square.png')
           .resolve(config)
           .addListener(ImageStreamListener((ImageInfo image, bool sync) async {
         final ByteData bytes =
             await image.image.toByteData(format: ImageByteFormat.png);
         final BitmapDescriptor bitmap =
             BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
         bitmapIcon.complete(bitmap);
       }));
    
       return await bitmapIcon.future;
     }
    

    如果您创建一个BitMapDescriptor变量,您可能只需要在添加标记之前第一次调用此函数,但不要忘记“wait”。

    还建议将另外两个较大尺寸的图像放在名为(2.0x&3.0x)的文件夹中,您可以在中看到分辨率 example images

        9
  •  1
  •   Bilal Şimşek    5 年前

    您可以将颤振小部件用于此类的自定义标记

    import 'package:flutter/material.dart';
    import 'dart:typed_data';
    import 'package:flutter/rendering.dart';
    import 'dart:ui' as ui;
    
    /// This just adds overlay and builds [_MarkerHelper] on that overlay.
    /// [_MarkerHelper] does all the heavy work of creating and getting bitmaps
    class MarkerGenerator {
      final Function(List<Uint8List>) callback;
      final List<Widget> markerWidgets;
    
      MarkerGenerator(this.markerWidgets, this.callback);
    
      void generate(BuildContext context) {
        WidgetsBinding.instance
            .addPostFrameCallback((_) => afterFirstLayout(context));
      }
    
      void afterFirstLayout(BuildContext context) {
        addOverlay(context);
      }
    
      void addOverlay(BuildContext context) {
        OverlayState overlayState = Overlay.of(context);
    
        OverlayEntry entry;
        entry = OverlayEntry(
            builder: (context) {
              return _MarkerHelper(
                markerWidgets: markerWidgets,
                callback: (List<Uint8List> bitmapList) {
                    // Given callback function
                    callback.call(bitmapList);
                    
                    // Remove marker widget stack from Overlay when finished
                    entry.remove();
                  },
              );
            },
            maintainState: true);
    
        overlayState.insert(entry);
      }
    }
    
    /// Maps are embeding GoogleMap library for Andorid/iOS  into flutter.
    ///
    /// These native libraries accept BitmapDescriptor for marker, which means that for custom markers
    /// you need to draw view to bitmap and then send that to BitmapDescriptor.
    ///
    /// Because of that Flutter also cannot accept Widget for marker, but you need draw it to bitmap and
    /// that's what this widget does:
    ///
    /// 1) It draws marker widget to tree
    /// 2) After painted access the repaint boundary with global key and converts it to uInt8List
    /// 3) Returns set of Uint8List (bitmaps) through callback
    class _MarkerHelper extends StatefulWidget {
      final List<Widget> markerWidgets;
      final Function(List<Uint8List>) callback;
    
      const _MarkerHelper({Key key, this.markerWidgets, this.callback})
          : super(key: key);
    
      @override
      _MarkerHelperState createState() => _MarkerHelperState();
    }
    
    class _MarkerHelperState extends State<_MarkerHelper> with AfterLayoutMixin {
      List<GlobalKey> globalKeys = [];
    
      @override
      void afterFirstLayout(BuildContext context) {
        _getBitmaps(context).then((list) {
          widget.callback(list);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Transform.translate(
              offset: Offset(MediaQuery.of(context).size.width, 0),
              child: Material(
                type: MaterialType.transparency,
                child: Stack(
                  children: widget.markerWidgets.map((i) {
                    final markerKey = GlobalKey();
                    globalKeys.add(markerKey);
                    return RepaintBoundary(
                      key: markerKey,
                      child: i,
                    );
                  }).toList(),
                ),
              ),
        );
      }
    
      Future<List<Uint8List>> _getBitmaps(BuildContext context) async {
        var futures = globalKeys.map((key) => _getUint8List(key));
        return Future.wait(futures);
      }
    
      Future<Uint8List> _getUint8List(GlobalKey markerKey) async {
        RenderRepaintBoundary boundary =
        markerKey.currentContext.findRenderObject();
        var image = await boundary.toImage(pixelRatio: 2.0);
        ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
        return byteData.buffer.asUint8List();
      }
    }
    
    /// AfterLayoutMixin
    mixin AfterLayoutMixin<T extends StatefulWidget> on State<T> {
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance
            .addPostFrameCallback((_) => afterFirstLayout(context));
      }
    
      void afterFirstLayout(BuildContext context);
    }
    

    用法示例

    import 'dart:typed_data';
    
    import 'package:flutter/material.dart';
    import 'package:google_maps_flutter/google_maps_flutter.dart';
    import 'package:map_marker_sample/gist/Gist.dart';
    
    class MapScreen extends StatefulWidget {
      @override
      _MapScreenState createState() => _MapScreenState();
    }
    
    class _MapScreenState extends State<MapScreen> {
      List<Marker> markers = [];
    
      @override
      Widget build(BuildContext context) {
        return Container(
            child: Stack(
              children: <Widget>[
                GoogleMap(
                  initialCameraPosition:
                      CameraPosition(target: LatLng(45.811328, 15.975862), zoom: 8),
                  markers: markers.toSet(),
                ),
              ],
            ),
        );
      }
    
      @override
      void initState() {
        super.initState();
    
        MarkerGenerator(markerWidgets(), (bitmaps) {
          setState(() {
            markers = mapBitmapsToMarkers(bitmaps);
          });
        }).generate(context);
      }
    
      List<Marker> mapBitmapsToMarkers(List<Uint8List> bitmaps) {
        List<Marker> markersList = [];
        bitmaps.asMap().forEach((i, bmp) {
          final city = cities[i];
          markersList.add(Marker(
              markerId: MarkerId(city.name),
              position: city.position,
              icon: BitmapDescriptor.fromBytes(bmp)));
        });
        return markersList;
      }
    }
    
    // Example of marker widget
    Widget _getMarkerWidget(String name) {
      return Container(
        padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 3, vertical: 1.5),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            border: Border.all(color: Colors.black, width: 1),
            color: Colors.white,
            shape: BoxShape.rectangle,
          ),
          child: Text(
            name,
            style: TextStyle(fontSize: 14, color: Colors.black),
          ),
        ),
      );
    }
    
    // Example of backing data
    List<City> cities = [
      City("Zagreb", LatLng(45.792565, 15.995832)),
      City("Ljubljana", LatLng(46.037839, 14.513336)),
      City("Novo Mesto", LatLng(45.806132, 15.160768)),
      City("Varaždin", LatLng(46.302111, 16.338036)),
      City("Maribor", LatLng(46.546417, 15.642292)),
      City("Rijeka", LatLng(45.324289, 14.444480)),
      City("Karlovac", LatLng(45.489728, 15.551561)),
      City("Klagenfurt", LatLng(46.624124, 14.307974)),
      City("Graz", LatLng(47.060426, 15.442028)),
      City("Celje", LatLng(46.236738, 15.270346))
    ];
    
    List<Widget> markerWidgets() {
      return cities.map((c) => _getMarkerWidget(c.name)).toList();
    }
    
    class City {
      final String name;
      final LatLng position;
    
      City(this.name, this.position);
    }
    

    源链接: https://infinum.com/the-capsized-eight/creating-custom-markers-on-google-maps-in-flutter-apps

    https://github.com/itsJoKr/markers_generator_sample

        10
  •  0
  •   Fakhriddin Abdullaev    7 年前

    更改标记图标

    MarkerOptions(
    position: LatLng(41.4219999, 63.0862462),
    infoWindowText: InfoWindowText("Yur Title", "Your Content"),
    icon: BitmapDescriptor.fromAsset('images/your_image.png',),
    ),
    
        11
  •  0
  •   mik    6 年前

    使用 flutter_map 插入 MapBox

    我尝试使用谷歌地图(GoogleMaps)来实现这一点,成功地在地图上呈现了动态web资产,但性能非常低。 有了MapBox,它非常棒,您可以直接使用小部件作为标记。