当前位置: 首页 > news >正文

flutter自定义地图Marker完美展示图片

世人都说雪景美

寒风冻脚无人疼

只道是一身正气

结论

参考Flutter集成高德地图并添加自定义Maker先实现自定义Marker。如果自定义Marker中用到了图片,那么会碰到图片没有被绘制到Marker的问题,此时需要通过precacheImage来预加载图片,从而解决此问题。

一、 背景

在高德地图上需要展示每一辆单车的电量。而amap_flutter_map确没有提供自定义Marker的方法,只有一个static BitmapDescriptor *fromBytes*(Uint8List byteData). 所以需要将定制的Widget转为图片,然后图片转为字节流,来实现自定义Marker

二、 自定义Marker

1. 定义widget

创建业务需求的widget,如下:

static Future<Widget> _createMarkerView(BuildContext context, String name,String imageName,{bool selected = false, MarkerTitleType markerTitleType = MarkerTitleType.small}) async {var height = markerTitleType.height;if (selected) {height *= 2;}var width = markerTitleType.width;return Container(height: height,constraints: BoxConstraints(minWidth: width),alignment: Alignment.center,decoration: BoxDecoration(image: DecorationImage(image: AssetImage(imageName)),),child: Directionality(textDirection: TextDirection.ltr,child: Text(name,style: TextStyle(fontSize: selected ? 22 : 14, color: Colors.white),maxLines: 1,overflow: TextOverflow.ellipsis,textAlign: TextAlign.center,),),);}

很简单的一个背景图片和一个标题。其中这个图片,因为是从Images资源中加载,会偶现加载失败的问题。

展示失败

2. widgetByteData

不展示widget到窗口,直接将widget保存为图片。代码如下:

  static Future<ByteData?> widgetToByteData(Widget widget, String imageName,{Alignment alignment = Alignment.center,Size size = const Size(double.maxFinite, double.maxFinite),double devicePixelRatio = 1.0,double pixelRatio = 1.0,required BuildContext context}) async {RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();RenderView renderView = RenderView(child: RenderPositionedBox(alignment: alignment, child: repaintBoundary),configuration: ViewConfiguration(size: size,devicePixelRatio: devicePixelRatio,),view: View.of(context),);PipelineOwner pipelineOwner = PipelineOwner();pipelineOwner.rootNode = renderView;renderView.prepareInitialFrame();BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());RenderObjectToWidgetElement rootElement = RenderObjectToWidgetAdapter(container: repaintBoundary,child: widget,).attachToRenderTree(buildOwner);await precacheImage(AssetImage(imageName), rootElement);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;}

其中的 await precacheImage(AssetImage(imageName), rootElement); 是解决图片偶现加载失败的关键。

3. 返回BitmapDescriptor

创建Marker的时候需要一个BitmapDescriptor,代码如下:

var data = await MapConverting.widgetToByteData(view, imageName,context: context,devicePixelRatio: AMapUtil.devicePixelRatio,pixelRatio: AMapUtil.devicePixelRatio,size: Size(selected ? width * 1.5 : width, selected ? height * 1.2 : height));var uInt8List = data?.buffer.asUint8List();if (null != uInt8List) {bitmapDescriptor = BitmapDescriptor.fromBytes(uInt8List);_createdBitmapDescriptor[key] = bitmapDescriptor;} else {bitmapDescriptor = await BitmapDescriptor.fromAssetImage(imageConfiguration, MyImages.imagesIcParkingNormal);}return bitmapDescriptor;

为了方便BitmapDescriptor的管理,可以创建一个BitmapDescriptorFactory类,添加一个static final Map<String, BitmapDescriptor> *_createdBitmapDescriptor* = {};将创建过的自定义BitmapDescriptorFactory做一个全局缓存,来解决重复创建的问题。

三、precacheImage使用注意

precacheImage函数中有一个参数是context,理解为缓存图片仅仅是在此context中生效。

尝试过在首页,业务主页,地图页面对需要使用到的图片进行缓存,都失效了,只有在RenderObjectToWidgetElement创建自定义widget时,将precacheImage缓存,才能生效。

参考: Flutter集成高德地图并添加自定义Maker

http://www.lryc.cn/news/264168.html

相关文章:

  • no module named cv2 、numpy 、xxx超全解决方案
  • BSWM 模式管理(二)ESH
  • mac电脑安装虚拟机教程
  • 手动配置 kafka 用户密码,认证方式等的方式
  • 机器学习 深度学习 神经网络
  • VCG 获取某个顶点的邻接顶点
  • 四川云汇优想教育咨询有限公司电商服务靠谱吗
  • Spring MVC框架支持RESTful,设计URL时可以使用{自定义名称}的占位符@Get(“/{id:[0-9]+}/delete“)
  • 【GoLang】哪些大公司正在使用Go语言
  • 美团外卖商超商品销量数据
  • 【C++高阶(八)】单例模式特殊类的设计
  • Linux之进程(五)(进程控制)
  • 63. 不同路径 II 23.12.21(二)
  • 【线性代数】两个向量组等价,其中一个向量组线性无关,另一个向量组也是线性无关吗?
  • c语言:指针作为参数传递
  • YOLOv5性能评估指标->mAP、Precision、Recall、FPS、Confienc (讲解论文关注的主要指标)
  • 陶建辉在 CIAS 2023 谈“新能源汽车的数字化”
  • PSP - 结构生物学中的机器学习 (NIPS MLSB Workshop 2023.12)
  • 某领先的集成电路研发中心:建立跨网交换平台 杜绝数据泄露风险
  • map|动态规划|单调栈|LeetCode975:奇偶跳
  • 从安全性角度,看“可信数字底座”有何价值
  • 软件设计模式:UML类图
  • 力扣题目学习笔记(OC + Swift)15. 三数之和
  • 想将电脑屏幕共享到iPhone上,但电脑是Linux系统,可行吗?
  • 大华 DSS 城市安防数字监控系统 SQL 注入漏洞
  • vue中的侦听器和组件之间的通信
  • maven-shade-plugin有什么用
  • 本地部署 OpenVoice
  • 【模式识别】解锁降维奥秘:深度剖析PCA人脸识别技术
  • 大模型赋能“AI+电商”,景联文科技提供高质量电商场景数据