1. 程式人生 > >基於高德地圖實現完全自定義Marker

基於高德地圖實現完全自定義Marker

  做地圖社交類APP開發的都知道,一般情況下,為了整體的美觀和使用者體驗度,我們需要定製化Marker的樣式。本文中實現的方式都是基於高德地圖的,百度地圖也類似,大家可以照葫蘆畫瓢,廢話不多說,先來看看最終效果:

最終自定義Marker效果

  • 實現思路:
    先來看看高德官方提供的設定Marker圖示的方法:

來自高德官方文件

我們可以看到setIcon()方法,裡面的引數BitmapDescriptor就是我們最終需要的東西。那麼到底該如何得到這個BitmapDescriptor物件呢,其實很簡單,該物件可以通過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物件的方式有多種,我們可以根據自己需要自行選擇。但是,為了應對頻繁的需求變化,我們肯定要選擇更為動態,靈活的方式來應付我們的需求變化,我們就可以選擇fromView()和fromBitmap()兩種方式來得到BitmapDescriptor物件了。這裡選用fromBitmap()方式來得到BitmapDescriptor物件吧,因為採用fromView()方法獲取後有個巨坑,這個後面再說。

  如果我們要根據需求自定義Marker,當然是希望能夠讓它可大可小,可動可靜了,那就非view莫屬了。只要我們可以自定義view佈局,然後轉化成bitmap不就OK了嗎,好,說幹就幹,我們以自定義Makrer樣式並載入網路圖片為例,開幹!

  1. 定製化Marker佈局,載入網路圖片:

    我們就以實現以下Marker的樣式為例:


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的圖示
     * @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) {
                        //待圖片載入完畢後再設定bitmapDes
                        icon.setImageBitmap(bitmap);
                        bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(markerView));
                        listener.markerIconLoadingFinished(markerView);
                    }
                });

    }

......

/**
     * by moos on 2017/11/15
     * func:自定義監聽介面,用來marker的icon載入完畢後回撥新增marker屬性
     */
    public interface OnMarkerIconLoadListener{
        void markerIconLoadingFinished(View view);
    }



這部分程式碼也不是很難,我就簡單講講思路。首先載入佈局後,拿到裡面的控制元件CircleImageView,並使用常用的Glide圖片載入框架來載入網路圖片。可能會有人問,為什麼關閉Glide的快取設定呢?關注到這點的人還是比較細心的,我們使用glide載入大量marker佈局的時候,如果社會了快取選項,那麼就可能會出現相同圖片只顯示一張的狀況,這個如果不信的話可以自行實驗。下面來說說另一個問題,也就是剛剛我們為什麼選擇fromBitmap()而不是fromView()方法,因為之前用fromView()時發現新增的第一個marker並不會加載出圖片,而只是顯示預設的佔位圖。即使通過在Glide載入圖片的回撥方法onResourceReady()設定也依然無效,這個問題大家不信邪也可以試試看看,這就是最終為什麼選擇fromBitmap()方法的原因。這裡還使用了自定義的介面來傳入markerView,方便後面的二次開發,然後在回撥方法markerIconLoadingFinished()方法中設定marker的圖示。
  1. 將view轉化為bitmap物件:
/**
     * by mos on 2017.11.13
     * func:view轉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;

    }

網上相關方法很多,這裡就不介紹了,有興趣可以去百度一下。

  1. 批量新增自定義的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也拿到了,那麼下面就簡單了,應該就不需要我多說了,只要注意一點,批量新增marker一般比較耗時,儘量放在子執行緒處理。

  到這裡,自定義marker就實現了,這應該可以適用於多數情況了,一路看下來,是不是也挺簡單的,只要用心思考研究就好了,而且搞定後有很強的工作動力有木有!

  最後,大家有任何問題或者建議,歡迎留言或者加群討論,謝謝.

程式碼地址https://github.com/Moosphan/AMapMarker-master此程式碼包含了自定義marker和marker的聚合功能,如果覺得對您有幫助,歡迎star~也同樣歡迎提出想法和需求來進一步完善它.

Android集中營

相關推薦

基於地圖實現完全定義Marker

  做地圖社交類APP開發的都知道,一般情況下,為了整體的美觀和使用者體驗度,我們需要定製化Marker的樣式。本文中實現的方式都是基於高德地圖的,百度地圖也類似,大家可以照葫蘆畫瓢,廢話不多說,先來看看最終效果: 實現思路: 先來看看高德官方提供的設

基於地圖實現移動網際網路地圖定位自動檢索系統

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>移動網際網路地圖定位自動檢索系統-熊盼</title> <

基於地圖實現的公交線路查詢功能

resource 返回 end 裏的 成功 文檔 地圖插件 osi con 高德地圖支持公交線程查詢功能。線上示例; 線上示例說明 接口返回的數據結構: path和via_stops字段詳情: ... path: [ { Q: 39.97741,

地圖api之定義載入地圖

高德地圖api有幾大功能模組:Amap,Location,Search,OfflineMap 首先我們檢視文件,並匯入Demo專案來學習一下basic map功能: 首先有幾個重要的類: 開啟jar package(Android_Map_V2.jar)中的packag

地圖JavaScript API 定義頂層Canvas與地圖互動

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <ti

地圖-添加定義圖標

click 的人 icon 100% text 我們 posit cti user 1、問題背景 這裏有張武漢市地圖,點擊按鈕在地圖上指定經度、緯度下添加小圖標 2、實現源碼 <!DOCTYPE html> <html> <

基於地圖為底圖實現全國、省、地級市下鑽

目錄 簡介 效果圖 具體實現 注意點 不足點 簡介 由於前面通過echarts和百度地圖都沒能實現理想效果從而只能另尋方案,最終實現方案:全國省採用echarts渲染,單個省、地級市採用高德地圖為地圖渲染(有人可能會疑問為什麼不全部採用高德地圖渲染,在上一篇中我

微信小程式-基於地圖API實現天氣元件(動態效果)

#### 微信小程式-基於高德地圖API實現天氣元件(動態效果) ​ 在社群翻騰了許久,沒有找到合適的天氣外掛。迫不得已,只好借鑑網際網路上的`web`專案,手動遷移到小程式中使用。現在分享到網際網路社群中,幫助後續有需要的開發者。 > 1.元件介紹 **1.1 元件效果預覽圖** ​ 小程

Unity與Android交互-Unity接入地圖實現定位以及搜索周邊的功能(使用Android Studio)詳細操作

nac mcc 以及 分享 pack create lis red 效果 剛進公司給安排的任務就是Unity接入高德地圖,算是踩了不少坑總算做出來了,抽點時間寫個博客記錄一下 廢話不多說 先上效果圖 獲取定位並根據手機朝向顯示周邊信息 使用的Unity

Android Studio之地圖實現定位和3D地圖顯示

tor uil track width 博客 5.0 eight ext wid 在應用開發中,地圖開發是常常須要使用的“組件”,國內比較出名的是就是百度地圖和高德地

基於地圖的描點操作,監聽地圖縮放,展示合理數量的marker

angle lease div href 函數 其中 如果 pla java 原文:基於高德地圖的描點操作,監聽地圖縮放,展示合理數量的marker 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.cs

採用地圖 實現打車功能程式碼

1:移動視角  要用:aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,

【android學習筆記】activity間的通訊案例之地圖實現天氣查詢

【概述】app實現天氣查詢是再正常不過的功能了,又因為往往不止一個activity去獲取資料,那就想到封裝一個類,需要時去呼叫獲取即可。 【注】因為看文件還有點懵,故將自己抓腦寫的程式碼記錄下,以便查詢 【思路】activity傳送請求--獲取地址--根據地址獲取天氣

基於地圖的android開發

首先:接入高德地圖第三方SDK——如何獲取API Key 一:登入---高德開發平臺 二:控制檯--》應用管理--》建立新的應用: 獲取除錯版SHA1安全碼 : 首先這不先別去看文件  看完之後你會更懵 找到build--》 點選creat new--》在

地圖實現

首先匯入依賴 implementation 'com.amap.api:location:4.4.0' 還有許可權 <!--用於進行網路定位--> <uses-permission android:name="android.permission.ACCESS_

Android基於地圖實時定位服務

Service功能有:實時定位(後臺進行) Service不會,去百度谷歌 功能有 實時定位(30秒間隔) 判斷是否在規定的時間段內 判斷距離是否大於規定的距離 判斷服務是否在開啟的狀態 服務程式碼:LocationService(Android

地圖實現公交路線-新增標記-軌跡回放-中心點-圖層

效果圖 軌跡回放 JSP <%@ page contentType="text/html;charset=UTF-8"%> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> &l

基於地圖的交通資料分析

前言 設計需求在於每天上班早高峰期,每次都提前出門,雖然有地圖可以實時檢視路況,但是再過一陣時間 就會異常的堵車如果通過資料監控分析每天指定路段在什麼時間段相應的擁堵情況,即可合理控制時間. 有時候很早出門,卻堵車堵得依然快遲到,而有時出門時間晚了,卻發現那個

微信小程式-路線規劃,地圖導航功能基於地圖API

主要實現微信小程式中的地圖路線規劃和地圖導航功能 小程式二維碼: 更新  2018年4月18日:新增限行限號查詢。 2018年5月7日:新增快遞查詢,模板訊息傳送。 準備 2、在微信小程式後臺把restapi.amap.com新增進request合法域名

Android地圖 實現定位 周邊熱點 POI搜尋 BottomSheetBehavior 動態獲取許可權demo

首先我們先看下效果 demo中包含了兩種不同風格的地圖定位效果展示,一種仿IOS的蘋果地圖實現的介面 地圖抽屜欄展示 通過手勢滑動可以實現底部欄的BottomSheetBehavior 可以通過上下拖拽 隱藏或者全屏效果 專案地址:https://github.com/xi