三步实现地图自定义InfoWindow
rtoe5728
8年前
<h3><strong>前言</strong></h3> <p>现在的app很多都需要接入地图,不同的app都会定义自己的marker以及InforWindow,本文以高德地图为例,描述自己自定义InfoWindow之路。</p> <p>先看看效果图:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/788ef8d46f1837e2f8c4edded9f3e7a4.png"></p> <p>高德地图的SDK以及接入流程,官方文档已经写的很明白了: <a href="/misc/goto?guid=4959732133617109766" rel="nofollow,noindex">http://lbs.amap.com/</a></p> <p><strong>第一步:自定义InforWindow的布局</strong></p> <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="127dp" android:background="#0000" > <LinearLayout android:layout_width="209dp" android:layout_height="127dp" android:orientation="vertical" android:background="@drawable/inforwindow_bg"> <TextView android:id="@+id/agent_name" android:layout_marginLeft="14dp" android:layout_marginRight="14dp" android:layout_marginTop="11dp" android:layout_width="match_parent" android:layout_height="20dp" android:textSize="14sp" android:textColor="@color/black_text"/> <TextView android:id="@+id/agent_addr" android:layout_marginLeft="14dp" android:layout_marginRight="14dp" android:layout_marginTop="2dp" android:layout_width="match_parent" android:layout_height="17dp" android:singleLine="true" android:textSize="12sp" android:textColor="@color/black_text2"/> <TextView android:id="@+id/waitNum" android:layout_marginLeft="14dp" android:layout_marginTop="2dp" android:layout_width="wrap_content" android:layout_height="17dp" android:textSize="12sp" android:textColor="#1DA1F2"/> <View android:layout_marginLeft="6dp" android:layout_marginRight="6dp" android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginTop="9dp" android:background="#DFDFDF"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_marginTop="9dp" android:id="@+id/navigation_LL" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" > <ImageView android:layout_marginLeft="27dp" android:layout_width="17dp" android:layout_height="18dp" android:scaleType="centerCrop" android:src="@drawable/inforwindow_navigation"/> <TextView android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/infowindow_navigation" android:textSize="14sp" android:textColor="@color/black_text"/> </LinearLayout> <View android:layout_width="1dp" android:layout_height="30dp" android:layout_marginTop="5dp" android:layout_marginBottom="13dp" android:background="#DFDFDF"/> <LinearLayout android:layout_marginTop="9dp" android:id="@+id/call_LL" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" > <ImageView android:layout_marginLeft="23dp" android:layout_width="19dp" android:layout_height="18dp" android:scaleType="centerCrop" android:src="@drawable/inforwindow_call"/> <TextView android:layout_marginLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/infowindow_call" android:textSize="14sp" android:textColor="@color/black_text"/> </LinearLayout> </LinearLayout> </LinearLayout> <!-- 用来偏移inforwindow的位置--> <TextView android:layout_width="38dp" android:layout_height="match_parent" /> </LinearLayout></code></pre> <p><strong>第二步、自定义适配器</strong></p> <p>需要继承高德地图的AMap.InfoWindowAdapter</p> <pre> <code class="language-java">package teprinciple.yang.amapinforwindowdemo.adapter; import android.content.Context; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.model.LatLng; import com.amap.api.maps2d.model.Marker; import teprinciple.yang.amapinforwindowdemo.base.BaseApplication; import teprinciple.yang.amapinforwindowdemo.R; import teprinciple.yang.amapinforwindowdemo.utils.NavigationUtils; import teprinciple.yang.amapinforwindowdemo.utils.PhoneCallUtils; /** * Created by Teprinciple on 2016/8/23. * 地图上自定义的infowindow的适配器 */ public class InfoWinAdapter implements AMap.InfoWindowAdapter, View.OnClickListener { private Context mContext = BaseApplication.getIntance().getBaseContext();; private LatLng latLng; private LinearLayout call; private LinearLayout navigation; private TextView nameTV; private String agentName; private TextView addrTV; private String snippet; @Override public View getInfoWindow(Marker marker) { initData(marker); View view = initView(); return view; } @Override public View getInfoContents(Marker marker) { return null; } private void initData(Marker marker) { latLng = marker.getPosition(); snippet = marker.getSnippet(); agentName = marker.getTitle(); } @NonNull private View initView() { View view = LayoutInflater.from(mContext).inflate(R.layout.view_infowindow, null); navigation = (LinearLayout) view.findViewById(R.id.navigation_LL); call = (LinearLayout) view.findViewById(R.id.call_LL); nameTV = (TextView) view.findViewById(R.id.name); addrTV = (TextView) view.findViewById(R.id.addr); nameTV.setText(agentName); addrTV.setText(String.format(mContext.getString(R.string.agent_addr),snippet)); navigation.setOnClickListener(this); call.setOnClickListener(this); return view; } @Override public void onClick(View v) { int id = v.getId(); switch (id){ case R.id.navigation_LL: //点击导航 NavigationUtils.Navigation(latLng); break; case R.id.call_LL: //点击打电话 PhoneCallUtils.call("028-"); //TODO 处理电话号码 break; } } }</code></pre> <p><strong>第三步、调用</strong></p> <pre> <code class="language-java">package teprinciple.yang.amapinforwindowdemo; import android.os.Bundle; import android.util.Log; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.CameraUpdateFactory; import com.amap.api.maps2d.MapView; import com.amap.api.maps2d.UiSettings; import com.amap.api.maps2d.model.BitmapDescriptorFactory; import com.amap.api.maps2d.model.LatLng; import com.amap.api.maps2d.model.Marker; import com.amap.api.maps2d.model.MarkerOptions; import teprinciple.yang.amapinforwindowdemo.adapter.InfoWinAdapter; import teprinciple.yang.amapinforwindowdemo.base.BaseActivity; import teprinciple.yang.amapinforwindowdemo.entity.Constant; import teprinciple.yang.amapinforwindowdemo.utils.CheckPermissionsActivity; public class MainActivity extends CheckPermissionsActivity implements AMap.OnMapClickListener, AMap.OnMarkerClickListener { private MapView mapView; private AMap aMap; private UiSettings uiSettings; private InfoWinAdapter adapter; private Marker oldMarker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); //在执行onCreateView时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理 mapView.onCreate(savedInstanceState); initOperation(); } private void initView() { mapView = (MapView) initV(R.id.mapView); } private void initOperation() { initMap(); } /** * 初始化地图 */ private void initMap() { if (aMap == null) { aMap = mapView.getMap(); uiSettings = aMap.getUiSettings(); aMap.setOnMapClickListener(this); } uiSettings.setZoomControlsEnabled(false); //隐藏缩放控件 //自定义InfoWindow aMap.setOnMarkerClickListener(this); adapter = new InfoWinAdapter(); aMap.setInfoWindowAdapter(adapter); addMarkerToMap(Constant.CHENGDU,"成都","中国四川省成都市"); } @Override public void onResume() { super.onResume(); mapView.onResume(); //管理地图的生命周期 } @Override public void onPause() { super.onPause(); mapView.onPause(); //管理地图的生命周期 } @Override public void onDestroy() { super.onDestroy(); mapView.onDestroy(); //管理地图的生命周期 } //地图的点击事件 @Override public void onMapClick(LatLng latLng) { //点击地图上没marker 的地方,隐藏inforwindow if (oldMarker != null) { oldMarker.hideInfoWindow(); oldMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.marker_normal)); } } //maker的点击事件 @Override public boolean onMarkerClick(Marker marker) { if (oldMarker != null) { oldMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.marker_normal)); } oldMarker = marker; marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.marker_selected)); return false; //返回 “false”,除定义的操作之外,默认操作也将会被执行 } private void addMarkerToMap(LatLng latLng, String title, String snippet) { aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f) .position(latLng) .title(title) .snippet(snippet) .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_normal)) ); } }</code></pre> <h3><strong>后记</strong></h3> <p>项目中还包括以下功能(均已适配6.0):</p> <p>1、跳转到高德地图进行导航功能</p> <p>2、定位功能</p> <p> </p> <p>来自:http://www.jianshu.com/p/8365b40d3829</p> <p> </p>