广州网站优化推广公司,WordPress小工具是什么,网站管理系统怎么用,网站备案多少天世人都说雪景美 寒风冻脚无人疼 只道是一身正气 结论
参考Flutter集成高德地图并添加自定义Maker先实现自定义Marker。如果自定义Marker中用到了图片#xff0c;那么会碰到图片没有被绘制到Marker的问题#xff0c;此时需要通过precacheImage来预加载图片#xff0c;从而解… 世人都说雪景美 寒风冻脚无人疼 只道是一身正气 结论
参考Flutter集成高德地图并添加自定义Maker先实现自定义Marker。如果自定义Marker中用到了图片那么会碰到图片没有被绘制到Marker的问题此时需要通过precacheImage来预加载图片从而解决此问题。
一、 背景
在高德地图上需要展示每一辆单车的电量。而amap_flutter_map确没有提供自定义Marker的方法只有一个static BitmapDescriptor *fromBytes*(Uint8List byteData). 所以需要将定制的Widget转为图片然后图片转为字节流来实现自定义Marker。
二、 自定义Marker
1. 定义widget
创建业务需求的widget如下
static FutureWidget _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. widget转ByteData
不展示widget到窗口直接将widget保存为图片。代码如下 static FutureByteData? 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 MapString, BitmapDescriptor *_createdBitmapDescriptor* {};将创建过的自定义BitmapDescriptorFactory做一个全局缓存来解决重复创建的问题。
三、precacheImage使用注意
precacheImage函数中有一个参数是context理解为缓存图片仅仅是在此context中生效。
尝试过在首页业务主页地图页面对需要使用到的图片进行缓存都失效了只有在RenderObjectToWidgetElement创建自定义widget时将precacheImage缓存才能生效。
参考 Flutter集成高德地图并添加自定义Maker