如果你是刚开始接触谷歌地图的话,推荐你先看一下文章:
Android Google Map 开发指南(一)解决官方demo显示空白只展示google logo问题
Android Google Map开发指南(二) 处理批量生成Marker点(添加大量标记点)内存消耗问题
如果你刚接触百度地图的话,推荐你可以看一下:
废话不多说,先来一波效果图:
实现前准备
要实现到这一步,就需要分别拿到google APIKEY 和 百度的APIKEY然后在你的应用中进行配置,google地图和百度地图的详细接入方法就在上面的文章中,当然你也可以去看看他们的官方文档,系统的学习。
好,那直接进入主题
一个小demo
为了减少我们在一个页面中进行两种地图的切换代码和兼容性考虑,我们这边不建议使用SupportMapFragment 的方式来显示google地图 ,这里强烈推荐使用goole提供的实例化MapView的方式来载入google地图
使用也非常简单,直接来看代码:
public class SecondActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mMapView;
private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
@Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GoogleMapOptions options = new GoogleMapOptions();
// //设置地图模式为卫星地图
options.mapType(GoogleMap.MAP_TYPE_NORMAL);
options.zoomControlsEnabled(true);
mMapView = new MapView(this, options);
setContentView(mMapView);
mMapView.onCreate(null);
mMapView.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
double lat = 39.937795;
double lng = 116.387224;
LatLng appointLoc = new LatLng(lat, lng);
map.addMarker(new MarkerOptions().position(appointLoc).title("Marker"));
map.moveCamera(CameraUpdateFactory.newLatLng(appointLoc));
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
mMapView.onSaveInstanceState(mapViewBundle);
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
代码就这么多 来看效果图(记得在Manifest文件中将APIKEY进行配置)
这里有个坑MapView生命周期注册非常重要,如果不设置生命周期一运行显示空白,只显示logo
接入思路
我这里同时接入是先实例化google的MapView和百度地图的Mapview,然后将它们放入我当前activity所对应布局中的指定父容器中,先都设置visible为gone,然后根据获取SharedPreferences中我指定的变量,默认加载上一次用户退出时使用的是google地图还是百度地图,当用户点击地图切换的图标时,可以对当前页面要显示的地图进行切换,这时设置选中的所对应的地图的visible为可见,这样我们在切换地图时就不会出现卡顿或突然黑一下屏幕的情况,提高用户体验,最后将新的变量值存储到SharedPreferences中方便下次调用
实现过程
public class MapStartActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mMapView = null;
private com.google.android.gms.maps.MapView googleMap = null;
private BaiduMap mBaiduMap;
private LocationClient mLocationClient;
private double startwei;
private double startjing;
private double mMBeiwei;
private double mDongjing;
private Boolean isfirstLocate = true;
private BitmapDescriptor mDefaultBitmap;
private LatLngBounds latlngBounds;
private String[] str = {"全部", "报警", "运行","停机","离线"};
private ImageView mapType;
private LinearLayout clickContainer,deviceMapWhere;
private LinearLayout mapContainer;
private TranslateAnimation translateAniShow, translateAniHide;
private AlphaAnimation alphaAniShow, alphaAniHide;
String addressStr = "no address \n";
private TextView address;
private LatLng myLatLng;
private LatLng endLatLng;
private MapSwitch mapSwitch;
private SharedPreferences sharedPreferences;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_show);
//对于布局中其他的控件及动画进行初始化
mapSwitch = new MapSwitch();
mapContainer = findViewById(R.id.view_container);
mapType = findViewById(R.id.device_map_type);
//初始化
initView();
initLanguage();
}
//先初始化goole/baidu 地图
private void initView() {
mapContainer.removeAllViews();
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
//百度地图初始化
BaiduMapOptions options = new BaiduMapOptions();
//设置地图模式为卫星地图
options.mapType(BaiduMap.MAP_TYPE_NORMAL);
//缩放控件/比例尺 显示出来
options.zoomControlsEnabled(true);
options.scaleControlEnabled(true);
mMapView = new MapView(this, options);
mMapView.setLayoutParams(layoutParams);
mMapView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
mapContainer.addView(mMapView);
mMapView.setVisibility(View.GONE);
mBaiduMap = mMapView.getMap();
//显示卫星图层
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//开启定位图层
mBaiduMap.setMyLocationEnabled(true);
//指南针打开
mBaiduMap.getUiSettings().setCompassEnabled(true);
//缩放按钮
mMapView.showZoomControls(true);
//TODO:: 设置我的位置图层出现
//定位初始化
mLocationClient = new LocationClient(this);
//通过LocationClientOption设置LocationClient相关参数
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
//设置locationClientOption
mLocationClient.setLocOption(option);
//注册LocationListener监听器
MyLocationListener myLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(myLocationListener);
//开启地图定位图层
mLocationClient.start();
//google地图初始化
GoogleMapOptions optionAction = new GoogleMapOptions();
//设置地图模式为卫星地图
optionAction.mapType(GoogleMap.MAP_TYPE_NORMAL);
optionAction.zoomControlsEnabled(true);
googleMap = new com.google.android.gms.maps.MapView(this,optionAction);
googleMap.setLayoutParams(layoutParams);
mapContainer.addView(googleMap);
googleMap.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
googleMap.setVisibility(View.GONE);
googleMap.onCreate(null);
googleMap.getMapAsync(this);
}
private void initLanguage() {
//获取表
sharedPreferences = getSharedPreferences(Contast.TABLE_TABLE, MODE_PRIVATE);
String mapType = sharedPreferences.getString(Contast.TABLE_MAPTYPE, "");
if(mapType.equals("")){
String language = sharedPreferences.getString(Contast.TABLE_LANGUAGE, "");
if(!language.equals("")){
if(language.equals("EN")){
mapType = "outland";
}else {
mapType = "inland";
}
}else {
mapType = "inland";
}
}
init(mapType);
//设置单选框选中
mapSwitch.setMapClick(mapType);
commitMethod(mapType);
}
private void commitMethod(String mapType) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(Contast.TABLE_MAPTYPE, mapType);
editor.apply();
}
private void updateWithNewLocation(LatLng latLng) {//获取相关位置信息
String coordinate;
if (latLng != null) {
mMBeiwei = latLng.latitude -0.004;
mDongjing = latLng.longitude - 0.01;
coordinate = "Latitude:" + mMBeiwei + "\nLongitude:" + mDongjing;
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(mMBeiwei,
mDongjing, 1);
StringBuilder sb = new StringBuilder();
if (addresses.size() > 0) {
Address address = addresses.get(0);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
sb.append(address.getAddressLine(i)).append(" ");
}
sb.append(address.getLocality()).append(" ");
Log.i("location", "address.getLocality()==" + address.getLocality());//城市名
sb.append(address.getSubLocality());
Log.i("location", "address.getSubLocality()=2=" + address.getSubLocality());//---区名
Log.i("location","all"+addressStr);
Log.i("location", "address.getSubLocality()=3=" + address.getAddressLine(0) + "");//---区名
//addressStr = sb.toString();
addressStr= address.getAddressLine(0) + "";
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
//如果用户没有允许app访问位置信息 则默认取上海松江经纬度的数据
/*lat = 39.25631486;
lng = 115.63478961;*/
coordinate = "no coordinate!\n";
}
Log.i("location", "经纬度为===" + coordinate);
Log.i("location", "地址为====" + addressStr);
}
//开始切换地图
private void init(String mapType) {
this.mapType.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mapSwitch.showAtLocation(clickContainer, Gravity.BOTTOM,0,0);
}
});
//地图选择
mapSwitch.setOnMapSelectedListener(new MapSwitch.onMapSelectedListener() {
@Override
public void onGoogleMapSelected() {
googleMap.setVisibility(View.VISIBLE);
mMapView.setVisibility(View.GONE);
commitMethod("outland");
mapSwitch.dismiss();
}
@Override
public void onBaiduMapSelected() {
googleMap.setVisibility(View.GONE);
mMapView.setVisibility(View.VISIBLE);
commitMethod("inland");
mapSwitch.dismiss();
}
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
double lat = 39.937795;
double lng = 116.387224;
com.google.android.gms.maps.model.LatLng appointLoc = new com.google.android.gms.maps.model.LatLng(lat, lng);
googleMap.addMarker(new com.google.android.gms.maps.model.MarkerOptions().position(appointLoc).title("Marker"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(appointLoc));
}
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//mapView 销毁后不在处理新接收的位置
if (location == null || mMapView == null){
return;
}
//移动到指定位置
navagitto(location);
startwei = location.getLatitude();
startjing = location.getLongitude();
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(location.getDirection()).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
}
}
//移动到指定位置
private void navagitto(BDLocation location) {
if(isfirstLocate){
// mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(5).build()));//设置缩放级别
//更新到指定的经纬度
myLatLng = new LatLng(location.getLatitude(),location.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(myLatLng);
mBaiduMap.animateMapStatus(update);
//设置缩放值
update = MapStatusUpdateFactory.zoomTo(6f);
mBaiduMap.animateMapStatus(update);
isfirstLocate = false;
}
}
@Override
protected void onResume() {
super.onResume();
if(mMapView!=null){
mMapView.onResume();
}
if(googleMap!=null){
googleMap.onResume();
}
}
@Override
protected void onStart() {
super.onStart();
if(googleMap!=null){
googleMap.onStart();
}
}
@Override
protected void onStop() {
super.onStop();
if(googleMap!=null){
googleMap.onStop();
}
}
@Override
protected void onPause() {
if(mMapView!=null){
mMapView.onPause();
}
if(googleMap!=null){
googleMap.onPause();
}
super.onPause();
}
@Override
protected void onDestroy() {
if(mMapView!=null){
mMapView.onDestroy();
}
if(googleMap!=null){
googleMap.onDestroy();
}
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
if(googleMap!=null){
googleMap.onLowMemory();
}
}
}
activity_map_show.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".activity.MapStartActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/back"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地图查看"
android:textSize="18sp"
android:textColor="#515151"
android:layout_centerInParent="true"
/>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/search_dark"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
/>
</RelativeLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/map_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabSelectedTextColor="@color/colorBlue"
app:tabRippleColor="@color/colorWhiteGray"
app:tabTextColor="@color/colorGray"
app:tabIndicatorColor="@color/colorBlue"
app:tabMode="fixed"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:gravity="center"
android:orientation="vertical"
android:id="@+id/view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
>
</LinearLayout>
<ImageView
android:id="@+id/device_map_type"
android:layout_alignParentBottom="true"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/shape_map_img"
android:src="@drawable/map_change"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="60dp"
/>
</RelativeLayout>
</LinearLayout>
MapSwitch.class
package com.example.smartgencloud.custom;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import com.example.smartgencloud.R;
import com.example.smartgencloud.base.BaseApplication;
public class MapSwitch extends PopupWindow {
private final View inflate;
private RadioButton google,baidu;
private RadioGroup group;
private onMapSelectedListener mapListener = null;
public MapSwitch(){
super(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
//这里要注意设置setOutsideTouchable之前要设置 setBackgroundDrawable()
//否则点击外部无法关闭pop
//setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setOutsideTouchable(true);
setFocusable(true);
inflate = LayoutInflater.from(BaseApplication.getAppContext()).inflate(R.layout.mark_click_pop, null);
setContentView(inflate);
//设置窗口进入和退出的动画
setAnimationStyle(R.style.pop_animation);
initView();
initEvent();
}
private void initView() {
group = inflate.findViewById(R.id.group);
google = inflate.findViewById(R.id.group_google);
baidu = inflate.findViewById(R.id.group_baidu);
}
public void setMapClick(String type){
if(type.equals("inland")){
baidu.setChecked(true);
}else {
google.setChecked(true);
}
}
private void initEvent() {
//单选按钮被选中后 将事件交由mapstart页面进行地图切换处理
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(mapListener!=null){
switch (checkedId){
case R.id.group_google:
mapListener.onGoogleMapSelected();
break;
case R.id.group_baidu:
mapListener.onBaiduMapSelected();
break;
}
}
}
});
}
public void setOnMapSelectedListener(onMapSelectedListener listener){
mapListener = listener;
}
public interface onMapSelectedListener{
void onGoogleMapSelected();
void onBaiduMapSelected();
}
}
mark_click_pop.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:background="@color/white"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/choose_map"
/>
<RadioGroup
android:id="@+id/group"
android:gravity="center"
android:drawableRight="@drawable/empty"
android:layout_width="match_parent"
android:layout_height="100dp"
>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorUnline"
/>
<RadioButton
android:id="@+id/group_google"
android:background="@color/white"
android:drawableRight="@drawable/select_radiobutton_img"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:button="@null"
android:padding="10dp"
android:textColor="@drawable/select_radiobutton_bg"
android:text="@string/map_google"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorUnline"
/>
<RadioButton
android:id="@+id/group_baidu"
android:background="@color/white"
android:padding="10dp"
android:button="@null"
android:textColor="@drawable/select_radiobutton_bg"
android:drawableRight="@drawable/select_radiobutton_img"
android:text="@string/map_baidu"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</RadioGroup>
</LinearLayout>
style.xml
<style name="pop_animation" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/pop_in</item>
<item name="android:windowExitAnimation">@anim/pop_out</item>
</style>
pop_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="100%"
android:duration = "300"
android:toYDelta="0"/>
<alpha
android:fromAlpha="0.8"
android:duration = "300"
android:toAlpha="1.0"/>
</set>
pop_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="0"
android:duration = "300"
android:toYDelta="100%"/>
<alpha
android:fromAlpha="1.0"
android:duration = "300"
android:toAlpha="0.8"/>
</set>
ok,到这里就结束了 有什么问题可以下面评论或者私信我,这边第一时间看到会及时回复你的哟
看都看到这里啦 ,请点赞支持一下啦 谢谢