Android高德地圖之多InfoWindow
本文是高德地圖系列的最後一文,因為光是寫這幾篇博文,就花去了我一整天時間,什麼也沒做,甚至飯也沒吃,做了一整天,現在身體已經空蕩蕩了,而且最近一段時間工作很忙,每天都很累,所以打算多去鍛鍊身體。有任何疑問也可以留言。
最終效果:生成marker並顯示詳情
由於不能上傳2M以上的截圖,只錄了重點,廢話不多講,速度上車。
Marker表示為地圖上的一個點,一個Point,我們可以在這個Marker做各種各樣的操作包括,拖動,獲取地理座標,反編譯地址等等。現在,我們要將Marker新增到地圖上,並達到圖上的效果。
在官方論壇上看到很多人不知道如何實現多InfoWindow的方法,基於此,我決定寫一篇關於實現多Infowindow的曲線救國的方式,按照我這篇文章,我相信你也能做出這種效果。
ok以我的專案為例,需求是在地圖顯示一種裝置的詳情,可以看到裝置ID,型別,次數,經緯度,反地理位置,時間,電量等等。下面是我的實體類BeanEvent 。
private Integer id;
private String deviceId;
private String simId;
private String eventId;
private String eventType;
private String eventCount;
private String latitude;
private String longitude;
private String eventTime;
private String actTime;
private String battery;
private String eventIp;
---此處省略get set方法
// 假資料
public static List<BeanEvent> getEvent()
{
List<BeanEvent> list = new ArrayList<>();
BeanEvent be1 = new BeanEvent();
be1. setDeviceId("devid--1111111");
be1.setSimId("simid--1111111");
be1.setEventId("event_1111111");
be1.setEventType("type-1111111");
be1.setEventCount("count_1111111");
be1.setLatitude("39.92746");
be1.setLongitude("116.396481");
be1.setEventTime("20170911");
be1.setBattery("1111111");
be1.setEventIp("1111111");
BeanEvent be2 = new BeanEvent();
be2.setDeviceId("devid--222222");
be2.setSimId("simid--22222");
be2.setEventId("event_22222");
be2.setEventType("type-22222");
be2.setEventCount("count_22222");
be2.setLatitude("39.93746");
be2.setLongitude("116.398681");
be2.setEventTime("20170911");
be2.setBattery("1111111");
be2.setEventIp("1111111");
BeanEvent be3 = new BeanEvent();
be3.setDeviceId("devid--33333");
be3.setSimId("simid--3333");
be3.setEventId("event_33333");
be3.setEventType("type-33333");
be3.setEventCount("count_33333");
be3.setLatitude("39.92956");
be3.setLongitude("116.399541");
be3.setEventTime("20170911");
be3.setBattery("1111111");
be3.setEventIp("1111111");
list.add(be1);
list.add(be2);
list.add(be3);
return list;
}
至此,資料來源被模擬出來了。
官方的新增marker的方法
/**
* 在地圖上新增marker
*/
private void addMarkersToMap() {
markerOption = new MarkerOptions().icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
.position(latlng)
.title("標題")
.snippet("詳細資訊")
.draggable(true);
marker = aMap.addMarker(markerOption);
marker.showInfoWindow();
}
新增InfoWindow的程式碼我就不演示了,太浪費大家時間,我會直接告訴你,官方程式碼裡的Marker的InfoWindow不支援多個同時顯示,當設定了多個Marker的Infowindow時,只顯示最後一個,這時該怎麼辦呢?
看看我是如何將他們顯示出來的
***初始化。。。
addMarkersToMap(getEvent()); // 新增點
/**
* 在地圖上新增marker
*/
private void addMarkersToMap(List<BeanEvent> eventList)
{
for (int i = 0; i < eventList.size(); i++)
{
BeanEvent be = eventList.get(i);
markerOption = new MarkerOptions().icon(BitmapDescriptorFactory
.fromView(getBitmapView(mActivity, be))).draggable(false);
markerOption.position(new LatLng(Double.parseDouble(be.getLatitude()), Double.parseDouble(be.getLongitude())));
marker = aMap.addMarker(markerOption);
marker.setObject(be);
markerList.add(marker);
}
}
其中,BitmapDescriptorFactory
.fromView(getBitmapView(mActivity, be))方法將返回一個View物件作為Marker的Icon,因此,這裡,我們可以藉助這個方法,實現將Marker與Infowindow結合在一起,即,看起來是marker和Infowindow,實際上,它們整體就是一個Marker。因為marker是多支援多個顯示的,所以這樣的思路是沒有問題的。
其方法是這樣寫的:
public static View getBitmapView(Context context, BeanEvent be)
{
LayoutInflater factory = LayoutInflater.from(context);
View view = factory.inflate(R.layout.item_marker_title, null);
TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
TextView tv_snippet = (TextView) view.findViewById(R.id.tv_snippet);
tv_title.setText("SIM卡號:" + be.getSimId());
tv_snippet.setText("公章ID:" + be.getDeviceId());
return view;
}
該方法將傳入的物件賦在對應的控制元件上,然後作為View返回。此時的預覽圖為
上圖就是我們最終作為marker的icon的圖,屆時,只需要傳入虛擬資料或真實資料,即可顯示出來。
此時多個InfoWindow就實現了。接下來,我們將實現點選marker彈出詳情。
我們先來看一下佈局結構:
<RelativeLayout
android:id="@+id/rl_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="2dp"
android:animateLayoutChanges="true"
android:background="@drawable/bg_seal_info"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:showDividers="middle"
android:visibility="gone"
app:divider="@drawable/iv_devider">
<TextView
android:id="@+id/tv_close"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:background="@mipmap/ic_seal"/>
<LinearLayout
android:id="@+id/ll_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<TextView
android:id="@+id/tv_sim"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="卡號:"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="次數:"
android:textSize="14sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ll_1"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/tv_sealNo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="公章號:"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_type"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="事件型別:"
android:textSize="14sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ll_2"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/tv_latitude"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="北緯:"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_longitude"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="東經:"
android:textSize="14sp"/>
</LinearLayout>
<TextView
android:id="@+id/tv_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ll_3"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:text="地址:"
android:textSize="14sp"/>
<LinearLayout
android:id="@+id/ll_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_address"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/tv_battery"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="電量:"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_ip"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="IP:"
android:textSize="14sp"/>
</LinearLayout>
</RelativeLayout>
效果為:
由於詳情中,用到了反地理編譯,即已知經緯度獲取地理位置。
所以我們在Activity中實現以下幾個介面:
implements GeocodeSearch.OnGeocodeSearchListener, AMap.OnMarkerClickListener
同時,將剛剛的佈局隱藏掉,作為一個介面卡使用:
public void setInfo(final RelativeLayout rl_layout, Marker marker, RegeocodeResult result)
{
ViewHolder viewHolder = null;
if (rl_layout.getTag() == null)
{
viewHolder = new ViewHolder();
viewHolder.tv_close = (TextView) rl_layout.findViewById(R.id.tv_close);
viewHolder.tv_sim = (TextView) rl_layout.findViewById(R.id.tv_sim);
viewHolder.tv_count = (TextView) rl_layout.findViewById(R.id.tv_count);
viewHolder.tv_sealNo = (TextView) rl_layout.findViewById(R.id.tv_sealNo);
viewHolder.tv_address = (TextView) rl_layout.findViewById(R.id.tv_address);
viewHolder.tv_latitude = (TextView) rl_layout.findViewById(R.id.tv_latitude);
viewHolder.tv_longitude = (TextView) rl_layout.findViewById(R.id.tv_longitude);
viewHolder.tv_battery = (TextView) rl_layout.findViewById(R.id.tv_battery);
viewHolder.tv_type = (TextView) rl_layout.findViewById(R.id.tv_type);
viewHolder.tv_ip = (TextView) rl_layout.findViewById(R.id.tv_ip);
rl_layout.setTag(viewHolder);
}
viewHolder = (ViewHolder) rl_layout.getTag();
BeanEvent be = (BeanEvent) marker.getObject();
viewHolder.tv_sim.setText("SIM::" + be.getSimId());
viewHolder.tv_count.setText("次數:" + be.getEventCount());
viewHolder.tv_sealNo.setText("公章號:" + be.getDeviceId());
viewHolder.tv_address.setText(result == null || result.getRegeocodeAddress() == null
|| result.getRegeocodeAddress().getFormatAddress() == null ? "地址:對不起,沒有找到相關地理位置!" : "地址:" + result.getRegeocodeAddress().getFormatAddress() + "附近");
viewHolder.tv_type.setText("型別:" + be.getEventType());
viewHolder.tv_latitude.setText("東經:" + be.getLatitude());
viewHolder.tv_longitude.setText("北緯:" + be.getLongitude());
viewHolder.tv_battery.setText("電量:" + be.getBattery());
viewHolder.tv_ip.setText("IP:" + be.getEventIp());
final ViewHolder finalViewHolder = viewHolder;
viewHolder.tv_close.setOnClickListener(v ->
{
rl_layout.startAnimation(AnimUtils.goneAnim());
rl_layout.setVisibility(View.GONE);
});
}
class ViewHolder
{
TextView tv_address, tv_close, tv_sim, tv_count, tv_sealNo, tv_type, tv_latitude, tv_longitude, tv_battery, tv_ip;
}
最後,當我們點選,marker的時候,將佈局顯示出來,此處要實現marker的onclicklistener方法:
animMove(aMap, marker.getPosition()); // 帶動畫的移動地圖到marker
MainActivity.instant.showToast("正在獲取地址資訊...");
// 發起地理編碼請求
if (rl_info.getVisibility() == View.VISIBLE) // 如果當前已經有詳情在顯示,先Gone掉
{
rl_info.startAnimation(AnimUtils.goneAnim());
rl_info.setVisibility(View.GONE);
}
RegeocodeQuery query = new RegeocodeQuery(convertToLatLonPoint(marker.getPosition()), 200, GeocodeSearch.AMAP);
geoSearch.getFromLocationAsyn(query);// 設定非同步逆地理編碼請求
return false;
接下來,在實現地理位置的實現方法:
@Override
public void onRegeocodeSearched(RegeocodeResult result, int i)
{
if (i == AMapException.CODE_AMAP_SUCCESS)
{
setInfo(rl_info, marker, result); // 將結果顯示在marker對應的詳情佈局上
rl_info.startAnimation(AnimUtils.showAnim());
rl_info.setVisibility(View.VISIBLE); // 顯示
} else MainActivity.instant.showToast("獲取地址失敗!請稍後重試!");
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i)
{
}
這樣,我們就實現了圖上的效果。
最後貼出MapUtils:
/**
* 把LatLng物件轉化為LatLonPoint物件
*/
public static LatLonPoint convertToLatLonPoint(LatLng latlon)
{
return new LatLonPoint(latlon.latitude, latlon.longitude);
}
/**
* 把LatLonPoint物件轉化為LatLon物件
*/
public static LatLng convertToLatLng(LatLonPoint latLonPoint)
{
return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
}
/**********************************************************移動地圖**************************************/
public static void animMove(AMap aMap, LatLng latLng)
{
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
public static void animMove(AMap aMap, LatLonPoint point)
{
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(convertToLatLng(point), 15));
}
public static void animMove(AMap aMap, AMapLocation location)
{
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 18));
}
至此,該功能已經完全實現。
請支援我,掃描左側二維碼打賞,謝謝。
相關推薦
Android高德地圖之多InfoWindow
本文是高德地圖系列的最後一文,因為光是寫這幾篇博文,就花去了我一整天時間,什麼也沒做,甚至飯也沒吃,做了一整天,現在身體已經空蕩蕩了,而且最近一段時間工作很忙,每天都很累,所以打算多去鍛鍊身體。有任何疑問也可以留言。 最終效果:生成marker並顯示詳情
Android高德地圖之基礎
最終效果圖1:選擇日曆選擇日期,其中有下標的日期是有資料的,點選顯示當天地圖上的資料 效果圖2: 生成marker並顯示詳情 由於不能上傳2M以上的截圖,只錄了重點,廢話不多講,速度上車。 - 申請賬號 http://lbs.amap.com
android-------高德地圖兩點路線和多個點路線繪制
分享圖片 下載 style ble use AD tps out font 最近朋友需要兩點路線和多個點路線繪制這個功能,幫忙弄了一下,寫這篇博客與大家分享一下。 兩點路線 是起點和終點兩個經緯度點,高德繪制出路線,可以實現實線和虛線功能 效果圖: 相關屬
Android----高德地圖多個Marker載入網路圖片出現圖片不顯示問題
需求說要地圖上展示的是mark,不是infowindow,加載出網路圖片,由於app的marker比較多,沒有達到需要的效果。 看了看高德地圖api中有這個方法 markerOption.icon(BitmapDescriptorFactory.fromBitmap(Bi
高德地圖自定義infowindow之點選不彈出訊息框
今天在開發過程中,突然產品來了一句地圖上面有要回到以前,再點選Marker的時候需要顯示一個自定義的訊息框,這時候,原本帶著非常陽光的心情上班,結果天氣預報也有不準的時候,我頓時有想搞他的心都有了(之前是他說要去掉這個訊息框),但是作為碼農的我們,當然沒有這個能
android 高德地圖的接入的demo
import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; import android.graphics.Color;
(六)高德地圖之駕車路線規劃
在專案中用到地圖的地方往往會有導航功能,那麼這一節將介紹一下使用高德地圖來實現駕車路線規劃的功能。 首先來兩張示例圖供參考: &nbs
(五)高德地圖之新增groundoverlay覆蓋物
本節主要實現的功能是往地圖上新增一個groundoverlay覆蓋物,用此方式可以實現公園電子導遊,下面先來看一張效果圖吧: 接下來我們還是直接上程式碼: 新建佈局檔案activity_groundoverlay.xml <?xml version="1.0" encod
(四)高德地圖之定位的幾種模式
這一節主要實現的功能是地圖定位的幾種模式,包括展示、定位、追隨、旋轉、旋轉位置、跟隨不移動中心點、旋轉不移動中心點、旋轉位置不移動到中心點,我們根據實際需要來選擇用那種模式。下面還是主要從程式碼中來體現,主要部分有註釋。 還是先新建佈局檔案:activity_locationmodesour
(三)高德地圖之自定義縮放及縮放動畫效果
這一節主要實現的功能是地圖的自定義縮放及縮放的動畫效果,還是直接放上程式碼更直觀些,主要部位裡面基本有註解 還是老樣子,首先是新建activity_zoom_animate.xml佈局檔案 <?xml version="1.0" encoding="utf-8"?> <
(二)高德地圖之手勢互動
上一結主要介紹瞭如何繼承高德地圖,以及地圖的幾種不同的顯示方式,那麼本節我們接著往下看,這一節主要介紹地圖的手勢互動功能,其中包括滑動手勢(地圖是否可以滑動)、縮放手勢(是否可以通過手勢放大縮小地圖)、切斜手勢以及旋轉手勢,另外又加了兩小部分,地圖的單擊、長按、觸控事件,比如點一下獲取地圖上點選
(一)高德地圖之基本屬性以及顯示模式
我們在開發中常常會用到地圖功能,那麼我們最常用的就是百度地圖和高德地圖了,今天我們就來看一下高德地圖怎麼用,我個人認為高德地圖封裝的還是比較好的,使用起來方便快捷。 首先我們需要到高德開發者平臺註冊賬號,根據API進行操作即可,高德開放平
Android 高德地圖自定義地圖覆蓋物(Marker)
先上效果圖,攝像頭和攝像頭上的預警事件紅點就是一個自定義佈局作為地圖的marker的圖示。 camera_red.png (素材圖) 官方提供的API參考手冊:http://
android 高德地圖marker連線
@Override public void getRouteEquipment(final AMap aMap, String signature, String echostr, String timestamp, final Context context, final
Android 高德地圖新增Marker,Marker點選事件
新增圖片圖示 BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.qidian)); final
高德地圖顯示多個多邊形框
<!--高德地圖開始 --> <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.4&key=""你的key"></script> <script src
高德地圖之軌跡回放
最近專案中有需要做車輛的軌跡回放功能,在這裡就給打分享一下還是挺簡單的。 <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Com
android高德地圖定位功能的實現
<1>先去高德開放平臺去申請開發者賬號,並且建立應用,獲取API Key <2>在清單檔案中配置key,其中value是應用的key值 <meta-data android:name="com.amap
Android——高德地圖設定中心點和縮放比例,獲取兩點之間距離
/** * 監聽amap地圖載入成功事件回撥 */ @Override public void onMapLoaded() { LatLng marker1 = new LatLng(39.90403, 116.407525);
Android高德地圖使用
在Swift基礎 - - 高德地圖實踐(一)中使用swift來使用高德地圖,這裡使用Android實踐高德地圖包含定位,移動地圖動畫,獲取網路資料,marker標記以及點選,Infowindow自定義介面以及點選,以及點選無marker地圖上面隱藏infowindow等功能。