三步实现地图自定义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>