【Flutter】Widget 转 Image,实现高德地图Marker自定义,大坑

目的是为了实现 高德地图Marker自定义,坑爹的只支持 本地素材 和 Uint8List,所以只能转换了。

网上搜 Widget 转 Image,基本都是需要在 build 内部实现,然后赋值一个key,生成 Uint8List。也就是将已经显示到页面上的 Widget 转成图片。
而地图的 Marker 需要在加载数据库时执行,显然不可行。

直接搜“高德地图Marker自定义”,还能搜到几篇文章。基本都是同一个答案,代码如下:

  static Future<ByteData> widgetToImage(
    Widget widget, {
    Alignment alignment = Alignment.center,
    Size size = const Size(double.maxFinite, double.maxFinite),
    double devicePixelRatio = 1.0,
    double pixelRatio = 1.0,
  }) async {
    RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();

    RenderView renderView = RenderView(
      child: RenderPositionedBox(alignment: alignment, child: repaintBoundary),
      configuration: ViewConfiguration(
        size: size,
        devicePixelRatio: devicePixelRatio,
      ),
      view: WidgetsBinding.instance.platformDispatcher.views.first,
    );

    PipelineOwner pipelineOwner = PipelineOwner();
    pipelineOwner.rootNode = renderView;
    renderView.prepareInitialFrame();

    BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
    RenderObjectToWidgetElement rootElement = RenderObjectToWidgetAdapter(
      container: repaintBoundary,
      child: widget,
    ).attachToRenderTree(buildOwner);
    buildOwner.buildScope(rootElement);
    buildOwner.finalizeTree();

    pipelineOwner.flushLayout();
    pipelineOwner.flushCompositingBits();
    pipelineOwner.flushPaint();

    ui.Image image = await repaintBoundary.toImage(pixelRatio: pixelRatio);
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);

    return byteData!;
  }

然后直接使用就会成这样,样式根本显示不出来


最终真是皇天不负苦心人,找到了坑。

问题点在这里:

调用的时候,一定要手动给于 Size 大小

    var byteData = await MapImageUtil.widgetToImage(widget, size: const Size(300, 400));
    return BitmapDescriptor.fromBytes(byteData.buffer.asUint8List());

真的是坑啊

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容