Android基于高德地圖完全自定義Marker的實(shí)現(xiàn)方法
前言
相信做地圖社交類APP開發(fā)的大家都知道,一般情況下,為了整體的美觀和用戶體驗(yàn)度,我們需要定制化Marker的樣式。本文中實(shí)現(xiàn)的方式都是基于高德地圖的,百度地圖也類似,大家可以照葫蘆畫瓢,廢話不多說,先來看看最終效果:
實(shí)現(xiàn)思路:
先來看看高德官方提供的設(shè)置Marker圖標(biāo)的方法:
我們可以看到setIcon()方法,里面的參數(shù)BitmapDescriptor就是我們最終需要的東西。那么到底該如何得到這個BitmapDescriptor對象呢,其實(shí)很簡單,該對象可以通過BitmapDescriptorFactory工廠類獲取,BitmapDescriptorFactory提供了以下方法來得到BitmapDescriptor對象:
/** * 1.通過資源id獲取 */ public static BitmapDescriptor fromResource(int var0) { ...... } /** * 2.通過自定義的view獲取 */ public static BitmapDescriptor fromView(View var0) { ...... } /** * 3.通過具體路徑資源獲取 */ public static BitmapDescriptor fromPath(String var0) { ...... } /** * 4.通過具體Assets資源獲取 */ public static BitmapDescriptor fromAsset(String var0) { ...... } /** * 5.通過具體文件獲取 */ public static BitmapDescriptor fromFile(String var0) { ...... } /** * 6.通過bitmap獲取 */ public static BitmapDescriptor fromBitmap(Bitmap var0) { ...... }
從以上官方提供的方法可以看到,得到BitmapDescriptor對象的方式有多種,我們可以根據(jù)自己需要自行選擇。但是,為了應(yīng)對頻繁的需求變化,我們肯定要選擇更為動態(tài),靈活的方式來應(yīng)付我們的需求變化,我們就可以選擇fromView()和fromBitmap()兩種方式來得到BitmapDescriptor對象了。這里選用fromBitmap()方式來得到BitmapDescriptor對象吧,因?yàn)椴捎胒romView()方法獲取后有個巨坑,這個后面再說。
如果我們要根據(jù)需求自定義Marker,當(dāng)然是希望能夠讓它可大可小,可動可靜了,那就非view莫屬了。只要我們可以自定義view布局,然后轉(zhuǎn)化成bitmap不就OK了嗎,好,說干就干,我們以自定義Makrer樣式并加載網(wǎng)絡(luò)圖片為例,開干!
1、定制化Marker布局,加載網(wǎng)絡(luò)圖片:
我們就以實(shí)現(xiàn)以下Marker的樣式為例:
這個樣式比較簡單,只要一個CircleImageView外面套一個固定的容器就可以了,直接看布局代碼:
marker_bg.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="40dp" android:layout_height="47dp" android:layout_gravity="center"> <RelativeLayout android:layout_width="40dp" android:layout_height="47dp" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:background="@mipmap/act_map_business_bg"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/marker_item_icon" android:layout_width="32dp" android:layout_height="32dp" android:src="@mipmap/userheadholder" android:layout_centerHorizontal="true" android:layout_marginTop="1dp" /> </RelativeLayout> </RelativeLayout>
下面看一下代碼中如何使用:
/** * by moos on 2017/11/13 * func:定制化marker的圖標(biāo) * @return */ private void customizeMarkerIcon(String url, final OnMarkerIconLoadListener listener){ final View markerView = LayoutInflater.from(this).inflate(R.layout.marker_bg,null); final CircleImageView icon = (CircleImageView) markerView.findViewById(R.id.marker_item_icon); Glide.with(this) .load(url+"!/format/webp") .asBitmap() .thumbnail(0.2f) .diskCacheStrategy(DiskCacheStrategy.NONE) .centerCrop() .into(new SimpleTarget<Bitmap>(){ @Override public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { //待圖片加載完畢后再設(shè)置bitmapDes icon.setImageBitmap(bitmap); bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(markerView)); listener.markerIconLoadingFinished(markerView); } }); } ...... /** * by moos on 2017/11/15 * func:自定義監(jiān)聽接口,用來marker的icon加載完畢后回調(diào)添加marker屬性 */ public interface OnMarkerIconLoadListener{ void markerIconLoadingFinished(View view); }
這部分代碼也不是很難,我就簡單講講思路。首先加載布局后,拿到里面的控件CircleImageView,并使用常用的Glide圖片加載框架來加載網(wǎng)絡(luò)圖片??赡軙腥藛?為什么關(guān)閉Glide的緩存設(shè)置呢?關(guān)注到這點(diǎn)的人還是比較細(xì)心的,我們使用glide加載大量marker布局的時(shí)候,如果社會了緩存選項(xiàng),那么就可能會出現(xiàn)相同圖片只顯示一張的狀況,這個如果不信的話可以自行實(shí)驗(yàn)。下面來說說另一個問題,也就是剛剛我們?yōu)槭裁催x擇fromBitmap()而不是fromView()方法,因?yàn)橹坝胒romView()時(shí)發(fā)現(xiàn)添加的第一個marker并不會加載出圖片,而只是顯示默認(rèn)的占位圖。即使通過在Glide加載圖片的回調(diào)方法onResourceReady()設(shè)置也依然無效,這個問題大家不信邪也可以試試看看,這就是最終為什么選擇fromBitmap()方法的原因。這里還使用了自定義的接口來傳入markerView,方便后面的二次開發(fā),然后在回調(diào)方法markerIconLoadingFinished()方法中設(shè)置marker的圖標(biāo)。
將view轉(zhuǎn)化為bitmap對象:
/** * by mos on 2017.11.13 * func:view轉(zhuǎn)bitmap */ public static Bitmap convertViewToBitmap(View view) { view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.buildDrawingCache(); Bitmap bitmap = view.getDrawingCache(); return bitmap; }
網(wǎng)上相關(guān)方法很多,這里就不介紹了,有興趣可以去百度一下。
批量添加自定義的Marker到地圖上:
先來看看代碼:
/** * by moos on 2017/11/15 * func:添加marker到地圖上顯示 */ BitmapDescriptor bitmapDescriptor ; private void addMarker(final ImageNearBean.DataBean.ExhibitionListBean bean) { double lat; double lon; lat = bean.getLatitude(); lon = bean.getLongitude(); LatLng latLng = new LatLng(lat, lon, false); loge("添加maker前的類型為==="+bean.getUserType()); String url = bean.getUserLogo(); final MarkerOptions markerOptions = new MarkerOptions(); markerOptions.setFlat(true); markerOptions.anchor(0.5f, 0.5f); markerOptions.position(new LatLng(lat, lon)); customizeMarkerIcon(url, bean.getTeamName(),new OnMarkerIconLoadListener() { @Override public void markerIconLoadingFinished(View view) { //bitmapDescriptor = BitmapDescriptorFactory.fromView(view); markerOptions.icon(bitmapDescriptor); Marker marker; marker = mAMap.addMarker(markerOptions); //marker.setObject(cluster); } }); } /** * by moos on 2017/11/15 * func:批量添加marker到地圖上 */ private void addMarkersToMap(){ runOnUiThread(new Runnable() { @Override public void run() { for(int i = 0;i<allBussinessBean.size();i++){ addMarker(allBussinessBean.get(i)); } } }); }
既然marker樣式定制完畢,BitmapDescriptor也拿到了,那么下面就簡單了,應(yīng)該就不需要我多說了,只要注意一點(diǎn),批量添加marker一般比較耗時(shí),盡量放在子線程處理。
到這里,自定義marker就實(shí)現(xiàn)了,這應(yīng)該可以適用于多數(shù)情況了,一路看下來,是不是也挺簡單的,只要用心思考研究就好了,而且搞定后有很強(qiáng)的工作動力有木有!
代碼地址:https://github.com/Moosphan/AMapMarker-master (本地下載)此代碼包含了自定義marker和marker的聚合功能,如果覺得對您有幫助,歡迎star~也同樣歡迎提出想法和需求來進(jìn)一步完善它.
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Android多媒體應(yīng)用使用SoundPool播放音頻
這篇文章主要為大家詳細(xì)介紹了Android多媒體應(yīng)用使用SoundPool播放音頻,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android訪問php取回json數(shù)據(jù)實(shí)例
Android訪問php取回json數(shù)據(jù),實(shí)現(xiàn)代碼如下,遇到訪問網(wǎng)絡(luò)的權(quán)限不足在AndroidManifest.xml中,需要進(jìn)行如下配置2013-06-06android實(shí)現(xiàn)緩存圖片等數(shù)據(jù)
本文給大家分享的是Android采用LinkedHashMap自帶的LRU 算法緩存數(shù)據(jù)的方法和示例,有需要的小伙伴可以參考下。2015-07-07Android pdf viewer在android studio應(yīng)用問題說明詳解
這篇文章主要介紹了Android pdf viewer在android studio應(yīng)用問題說明的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09Android自定義控件之創(chuàng)建可復(fù)用的組合控件
這篇文章主要為大家詳細(xì)介紹了Android自定義控件之創(chuàng)建可復(fù)用的組合控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12關(guān)于Android輸入法彈窗bug的優(yōu)雅處理
在Android應(yīng)用中,當(dāng)跳轉(zhuǎn)到某個Activity時(shí),該Activity顯示頁面的EditText獲得焦點(diǎn),在某些機(jī)器中會觸發(fā)軟鍵盤的自動彈出,這篇文章主要給大家介紹了關(guān)于Android輸入法彈窗bug的優(yōu)雅處理,需要的朋友可以參考下2021-10-10Android EditText 實(shí)現(xiàn)監(jiān)聽實(shí)例
本文主要介紹Android EditText 組件 實(shí)現(xiàn)監(jiān)聽事件,并附有代碼實(shí)例,在Android開發(fā)過程中如果能用到可以參考下2016-07-07Flutter底部不規(guī)則導(dǎo)航的實(shí)現(xiàn)過程
這篇文章主要給大家介紹了關(guān)于Flutter底部不規(guī)則導(dǎo)航的實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08