【问题标题】:How to display text text on google map marker in flutter如何在颤动的谷歌地图标记上显示文本
【发布时间】:2022-01-03 19:59:12
【问题描述】:

我想在我当前的标记上添加一个文本,但是当我尝试将label 添加到标记时,它会抛出未定义的错误。在javascript api中,我是这样做的:

       const marker = new google.maps.Marker({
            position: { lat: item.position.lat, lng: item.position.lon },
            label: `${item.sort}`,

【问题讨论】:

    标签: flutter


    【解决方案1】:

    据我所知,您只能使用标记图标来做到这一点,方法是使用画家将您的文本渲染为图像并将此图像显示为标记的图标。

    有关示例,请参阅 https://stackoverflow.com/a/63201170/1151983https://stackoverflow.com/a/58173697/1151983

    更新:以下示例展示了如何在同一画布上使用多个画家。第一位画家创建了一个价格标签标记。第二个将品牌名称写在画布上。在您的示例中,这可能是标签。

    Future<BitmapDescriptor> _getSinglePriceTag({
        required String price,
        required String brandName,
      }) async {
       
        String resolutionPathModifier;
        resolutionPathModifier = _getResolutionPathModifier(pixelRatio);
    
        final singleTagImage =
            await load('assets/tags/${resolutionPathModifier}pricetag_head.png');
        final superScriptPrice = getSuperScriptPrice(price);
        final width = singleTagImage.width.toDouble();
        final height = singleTagImage.height.toDouble();
        final widthAsInt = width.floor();
        final heightAsInt = height.floor();
    
        final pictureRecorder = ui.PictureRecorder();
    
        final canvas = Canvas(pictureRecorder);
        final priceTagPainter = PriceTagPainter(
          singleTagImage,
          price: superScriptPrice,
          pixelRatio: pixelRatio,
        );
        final brandPainter = BrandPainter(
          singleTagImage,
          pixelRatio: pixelRatio,
          brandName: brandName,
        );
        priceTagPainter.paint(canvas, Size(width, height));
        brandPainter.paint(canvas, Size(width, height));
    
        final recordedPicture = pictureRecorder.endRecording();
        final img = await recordedPicture.toImage(widthAsInt, heightAsInt);
        final data = await img.toByteData(format: ui.ImageByteFormat.png);
    
        return BitmapDescriptor.fromBytes(data!.buffer.asUint8List());
      }
    

    画家可能是这样的。

    class PriceTagPainter extends CustomPainter {
      PriceTagPainter(
        this.priceTagImage, {
        required this.price,
        required this.pixelRatio,
      });
    
      static const textStyle = TextStyle(
        color: Colors.black,
        fontFamily: 'OpenSans',
      );
    
      final String price;
      final double pixelRatio;
      final ui.Image priceTagImage;
    
      @override
      void paint(Canvas canvas, Size size) {
        canvas.drawImage(priceTagImage, Offset.zero, Paint());
    
        final textSpan = TextSpan(
          text: price,
          style: textStyle,
        );
    
        final textPainter = TextPainter(
          text: textSpan,
          textDirection: TextDirection.ltr,
          textScaleFactor: pixelRatio,
        )..layout(
            maxWidth: size.width,
          );
    
        final dx = (size.width - textPainter.width + 5) * 0.5;
        final dy = (size.height - textPainter.height) * 0.6;
        final offset = Offset(dx, dy);
        textPainter.paint(canvas, offset);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }
    

    它创造了这样的东西。

    【讨论】:

    • 这就是我生成图标i.imgur.com/hNirbYn.png的方式,然后我将pinLocationicon作为图标传递,是否可以使用上述方法在我的图像上添加自定义文本?
    • 你需要结合画家。首先绘制标记的图形,然后使用第二个文本画家编写标签文本。
    • 什么是final ui.Image?我正在获取未定义的 ui 图像。什么是 Brand Painter、load、getResolutionPathModifier?我的应用中没有类似的东西
    • 这似乎过于复杂,我只需要在标记上添加一个文本,我需要所有这些?
    • 如果您找到更简单的解决方案,请告诉我:D BrandPainter 是我的画家实现,它将加油站的品牌名称作为文本绘制到标记的顶部区域。它只是类似于PriceTagPainter 的第二个画家。 getResolutionPathModifier 是一个辅助方法,它根据用户设备的设备像素比选择正确的资产。你可以忽略它,它会加载一个 PNG 作为背景图形。
    【解决方案2】:

    这个包将准确地为您提供您在问题中描述的内容。使用 CustomMarker 小部件;您可以传递标签参数,就像您在预期结果中提到的那样。 .

    https://pub.dev/packages/label_marker .

    例子

    markers.addLabelMarker(LabelMarker(
        label: "TextToShow",
        markerId: MarkerId("idString"),
        position: LatLng(10.0, 11.0),
        backgroundColor: Colors.green,
        )).then((value) {
        setState(() {});
        },
    );
    

    【讨论】:

    • 也不错
    【解决方案3】:

    您可以使用 GoogleMapController 的 showMarkerInfoWindow 属性

    final GoogleMapController controller = await _controller.future;
    controller.showMarkerInfoWindow(MarkerId('ID_MARKET'));
    

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 2021-07-07
      • 2015-01-25
      • 2021-03-05
      • 1970-01-01
      相关资源
      最近更新 更多