Flutter 高德地圖之自定義Marks

image.png

高德地圖插件大家想必已經(jīng)不陌生了(不熟的去看上一篇)掠归,按產(chǎn)品需求開發(fā)時需要在地圖上展示自定義的Mark峦失,觀察Mark方法:

(new) Marker Marker({
        required LatLng position,
        double alpha = 1.0,
        Offset anchor = const Offset(0.5, 1.0),
        bool clickable = true,
        bool draggable = false,
        BitmapDescriptor icon = BitmapDescriptor.defaultMarker,
        bool infoWindowEnable = true,
        InfoWindow infoWindow = InfoWindow.noText,
        double rotation = 0.0,
        bool visible = true,
        double zIndex = 0.0,
        void Function(String)? onTap,
        void Function(String, LatLng)? onDragEnd,
    })

發(fā)現(xiàn)并沒有 Mark widget,沒有widget就意味著無法自定義widget迁筛,這可如何是好冈止,但聰明的我又怎會被這小小的難題困住酌媒,百度、谷歌??疑難解答不懂就問這是個好習慣耸弄,找到了解決思路咧虎,以BitmapDescriptor icon為突破口。

通過觀察BitmapDescriptor發(fā)現(xiàn)提供了展示png字節(jié)的方法:

static BitmapDescriptor fromBytes(Uint8List byteData) {
   return BitmapDescriptor._(<dynamic>['fromBytes', byteData]);
 }

至此是不是就明了了计呈,只需將自定義的widget轉(zhuǎn)為png在轉(zhuǎn)為ByteData即可砰诵。

wiget->ByteData:

 Future<ByteData?> widgetToByteData(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,
     ),
     window: ui.window,
   );

   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;
 }

此方法直接copy拿走,多費一點腦子算我輸捌显,實現(xiàn)思路已OK

附上完整的代碼:

import 'dart:ui' as ui;
.
.
 AMapWidget? map;
 Map<String, Marker> initMarkerMap = <String, Marker>{};
 AMapController? _mapController;

 late BitmapDescriptor icon;

 ///自定義地圖mark的 widget轉(zhuǎn)字節(jié)
 Future<ByteData?> widgetToByteData(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,
     ),
     window: ui.window,
   );

   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;
 }

///自定義widget
 widgetContext( ) {
   return Container(
     width: 540.w,
     height: 180.h,
     decoration: BoxDecoration(
         border:
             Border.all(width: 5.w, color: Color.fromRGBO(236, 253, 255, 1)),
        color: Colors.white,
         borderRadius: BorderRadius.only(
             topLeft: Radius.circular(70.r),
             topRight: Radius.circular(70.r),
             bottomRight: Radius.circular(70.r),
             bottomLeft: Radius.circular(12.r))),
     child: Column(
       mainAxisAlignment: MainAxisAlignment.center,
       children: [
             ···       
       ],
     ),
   );
 }

 ///添加自定義mark
 addMark() async {
     ByteData? byteData =
         await widgetToByteData(widgetContext());
     icon = BitmapDescriptor.fromBytes(byteData!.buffer.asUint8List());
     Marker marker = Marker(
       infoWindowEnable: false,
       position: LatLng(double.parse(item['lat'].toString()),
           double.parse(item['lng'].toString())),
       icon: icon,
       anchor: const Offset(0, 1.0),
     );
     initMarkerMap[marker.id] = marker;
   }
   setState(() {
     map = AMapWidget(
       mapType: MapType.bus,
       labelsEnabled: false,
       onLocationChanged: (argument) {
         onLocationChangeds(argument);
       },
       myLocationStyleOptions: MyLocationStyleOptions(false),
       privacyStatement: AmapConfig.amapPrivacyStatement,
       apiKey: AmapConfig.amapApiKeys,
       onMapCreated: onMapCreated,
       markers: Set<Marker>.of(initMarkerMap.values),
     );
   });
 }
@override
 void initState() {
   // TODO: implement initState
   super.initState();
   addMark();
 }

如果到此處本文完結(jié)那和別的文章也就沒什么不同之處了茁彭,注意??有兩處坑

a.對于Text的定義要用

Directionality(
           textDirection: TextDirection.ltr,
           child:Text('')
        )

b.自定義的widget只能縱向布局因此可采用富文本來解決橫向布局需求 RichText()

====== 嫖走吧,有良心的就點點贊加個關(guān)注$$ =======

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扶歪,一起剝皮案震驚了整個濱河市理肺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌善镰,老刑警劉巖妹萨,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異媳禁,居然都是意外死亡眠副,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門竣稽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來囱怕,“玉大人,你說我怎么就攤上這事毫别⊥薰” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵岛宦,是天一觀的道長台丛。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么挽霉? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任防嗡,我火速辦了婚禮,結(jié)果婚禮上侠坎,老公的妹妹穿的比我還像新娘蚁趁。我一直安慰自己,他們只是感情好实胸,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布他嫡。 她就那樣靜靜地躺著,像睡著了一般庐完。 火紅的嫁衣襯著肌膚如雪钢属。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天门躯,我揣著相機與錄音淆党,去河邊找鬼。 笑死讶凉,一個胖子當著我的面吹牛宁否,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缀遍,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饱须!你這毒婦竟也來了域醇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蓉媳,失蹤者是張志新(化名)和其女友劉穎譬挚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酪呻,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡减宣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了玩荠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漆腌。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阶冈,靈堂內(nèi)的尸體忽然破棺而出闷尿,到底是詐尸還是另有隱情,我是刑警寧澤女坑,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布填具,位于F島的核電站,受9級特大地震影響匆骗,放射性物質(zhì)發(fā)生泄漏劳景。R本人自食惡果不足惜誉简,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盟广。 院中可真熱鬧闷串,春花似錦、人聲如沸衡蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毛甲。三九已至年叮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玻募,已是汗流浹背只损。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留七咧,地道東北人跃惫。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像艾栋,于是被迫代替她去往敵國和親爆存。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容