最终效果:
1.gradle里添加高德地图依赖
implementation 'com.amap.api:map2d:latest.integration'//2d地图功能
implementation 'com.amap.api:location:latest.integration'//定位功能
2.如果要用到定位的话,就首先到高德控制台里面加入本应用的信息获取到key,再在Application里设置key,并在AndroidManifest.xml中应用MainApp
public class MainApp extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
//高德地图注册
AMapLocationClient.setApiKey("0f1d26a891783cc4d632965a7cc08443");
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hk.testapplication">
<uses-permission android:name="android.permission.INTERNET" /> <!-- 访问网络权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<application
android:name=".MainApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TestApplication">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
3. 创建activity_main.xml地图布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.amap.api.maps2d.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.amap.api.maps2d.MapView>
</androidx.constraintlayout.widget.ConstraintLayout>
4. MainActivity里加载地图,添加marker
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapView = findViewById(R.id.mapview);
mMapView.onCreate(savedInstanceState);// 此方法必须重写
mMap = mMapView.getMap();
initPoint(30.665534,104.070929); //地图中心点位
initMarker();//测试点位
}
/**
* 绘制marker
*/
private void initMarker() {
mMarkers = new ArrayList<>();
//绘制marker 实际使用时会循环创建marker并填入数据
Marker marker = mMap.addMarker(new MarkerOptions()
.anchor(0.5f, 0.5f)
.position(new LatLng(30.665534,104.070929))
.title("标题数据")
.snippet("消息数据")
.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(getResources(), R.mipmap.ic_launcher_round))));//点位图标
mMarkers.add(marker);
}
/**
* 加载地图中心点
*/
private void initPoint(double latitude, double Longitude) {
LatLng marker1 = new LatLng(latitude, Longitude);
mMap.moveCamera(CameraUpdateFactory.changeLatLng(marker1));
mMap.moveCamera(CameraUpdateFactory.zoomTo(12));
}
@Override
public void onResume() {
super.onResume();
if (mMapView != null)
mMapView.onResume(); //管理地图的生命周期
}
@Override
public void onPause() {
super.onPause();
if (mMapView != null)
mMapView.onPause(); //管理地图的生命周期
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMapView != null)
mMapView.onDestroy(); //管理地图的生命周期
}
}
5.添加弹框自定义布局view_map_infowindow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:minHeight="50dp"
android:minWidth="100dp"
android:background="#ffff"
android:gravity="center"
>
<ImageView
android:id="@+id/iv_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:id="@+id/tv_msg"
android:text="自定义布局"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
记得设置布局最小高度和宽度,不然窗口会默认宽度高度,会使布局显示不完整
6.添加自定义弹框窗口adapter
/**
*自定义地图弹框adapter
* @author hk
*/
public class MapInfoWinAdapter implements AMap.InfoWindowAdapter, View.OnClickListener {
private Context mContext;
private LatLng latLng;
private TextView mTvMsg;
private ImageView mIvLeft,mIvRight;
private String mSnippet,mTitle;
@Override
public View getInfoWindow(Marker marker) {
initData(marker);
View view = initView();
return view;
}
@Override
public View getInfoContents(Marker marker) {
return null; //因为是自定义的布局,返回null
}
public MapInfoWinAdapter(Context context) {
mContext = context;
}
private void initData(Marker marker) {
//当前点位经纬度
latLng = marker.getPosition();
//当前点位带的消息信息 也可通过这个传输数据把数据转成json
mSnippet = marker.getSnippet();
//当前点位带的标题信息
mTitle = marker.getTitle();
}
@NonNull
private View initView() {
//获取自定义的布局
View view = LayoutInflater.from(mContext).inflate(R.layout.view_map_infowindow, null);
mTvMsg = (TextView) view.findViewById(R.id.tv_msg);
mIvLeft= (ImageView) view.findViewById(R.id.iv_left);
mIvRight= (ImageView) view.findViewById(R.id.iv_right);
mTvMsg.setText("我是自定义布局弹框");
mIvLeft.setOnClickListener(this);
mIvRight.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_left:
Toast.makeText(mContext,"我是左边按钮点击事件",Toast.LENGTH_SHORT).show();
break;
case R.id.iv_right:
Toast.makeText(mContext,"我是右边按钮点击事件",Toast.LENGTH_SHORT).show();
break;
}
}
}
7.地图绑定adapter
//重要 创建自定义适配器
MapInfoWinAdapter adapter = new MapInfoWinAdapter(this);
mMap.setInfoWindowAdapter(adapter);//设置自定义窗口adapter
现在点击marker就会弹出我们自定义的布局了
8.点击地图或弹框关闭弹框窗口
mMap.setOnInfoWindowClickListener(this);//弹框窗口点击事件
mMap.setOnMapClickListener(this);//地图点击事件
@Override
public void onMapClick(LatLng latLng) {
//点击地图区域关闭所有窗口
for (Marker marker : mMarkers) {
marker.hideInfoWindow();
}
}
@Override
public void onInfoWindowClick(Marker marker) {
if (marker.isInfoWindowShown()) {
marker.hideInfoWindow();//再次点击窗口就隐藏窗口
}
}
到此自定义弹框窗口就完成了,以下为完整MainActivity代码
public class MainActivity extends AppCompatActivity implements AMap.OnInfoWindowClickListener, AMap.OnMapClickListener {
private AMap mMap;
private List<Marker> mMarkers;
private MapView mMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapView = findViewById(R.id.mapview);
mMapView.onCreate(savedInstanceState);// 此方法必须重写
mMap = mMapView.getMap();
mMap.setOnMapClickListener(this);//地图点击事件
initPoint(30.665534,104.070929); //地图中心点位
initMarker();//测试点位
}
/**
* 绘制marker
*/
private void initMarker() {
mMarkers = new ArrayList<>();
//重要 创建自定义适配器
MapInfoWinAdapter adapter = new MapInfoWinAdapter(this);
mMap.setInfoWindowAdapter(adapter);//设置自定义窗口adapter
mMap.setOnInfoWindowClickListener(this);
//绘制marker 实际使用时会循环创建marker并填入数据
Marker marker = mMap.addMarker(new MarkerOptions()
.anchor(0.5f, 0.5f)
.position(new LatLng(30.665534,104.070929))
.title("标题数据")
.snippet("消息数据")
.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(getResources(), R.mipmap.ic_launcher_round))));//点位图标
mMarkers.add(marker);
}
/**
* 加载地图中心点
*/
private void initPoint(double latitude, double Longitude) {
LatLng marker1 = new LatLng(latitude, Longitude);
mMap.moveCamera(CameraUpdateFactory.changeLatLng(marker1));
mMap.moveCamera(CameraUpdateFactory.zoomTo(12));
}
@Override
public void onMapClick(LatLng latLng) {
//点击地图区域关闭所有窗口
for (Marker marker : mMarkers) {
marker.hideInfoWindow();
}
}
@Override
public void onInfoWindowClick(Marker marker) {
if (marker.isInfoWindowShown()) {
marker.hideInfoWindow();//再次点击窗口就隐藏窗口
}
}
@Override
public void onResume() {
super.onResume();
if (mMapView != null)
mMapView.onResume(); //管理地图的生命周期
}
@Override
public void onPause() {
super.onPause();
if (mMapView != null)
mMapView.onPause(); //管理地图的生命周期
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMapView != null)
mMapView.onDestroy(); //管理地图的生命周期
}
}