上兩篇文章我們介紹使用了百度地圖的一些功能,這一篇文章我打算在原來(lái)的基礎(chǔ)上對(duì)界面做一些美化,當(dāng)然這個(gè)美化是基于我們百度地圖,高德地圖的UI界面來(lái)處理,我們對(duì)這個(gè)界面進(jìn)行模仿。
我也希望這個(gè)Demo最后不僅僅是個(gè)Demo,而是能拿的出手的一個(gè)像樣的APP。
首先我們看一下百度的主界面。
我們分析一下主界面,一個(gè)搜索框,一個(gè)羅盤(pán)圖標(biāo),一排功能鍵,一個(gè)定位按鈕和上報(bào)按鈕,一個(gè)路線(xiàn)按鈕和一個(gè)底欄。當(dāng)然我們今天不是從做UI入手,而是先解決一些和地圖相關(guān)的界面細(xì)節(jié)。
1.定位圖層相關(guān)
上一篇文章我們實(shí)現(xiàn)了定位圖層,也就是那個(gè)小藍(lán)點(diǎn),可是小藍(lán)點(diǎn)還是不夠的,我們還能更進(jìn)一步操作。
先看一下修改后的代碼
lati_ = bdLocation.getLatitude();
long_ = bdLocation.getLongitude();
//顯示定位圖標(biāo)
MyLocationData locData = new MyLocationData.Builder()
// 不顯示半徑圓圈
.accuracy(0)
// 此處設(shè)置開(kāi)發(fā)者獲取到的方向信息,順時(shí)針0-360
.direction(bdLocation.getDirection()).latitude(lati_)
.longitude(long_).build();
//使用自定義圖標(biāo)
BitmapDescriptor mIconLocation = BitmapDescriptorFactory.fromResource(R.drawable.main_icon_follow);
//配置(定位模式,允許顯示方向,圖標(biāo))
MyLocationConfiguration configuration
=new MyLocationConfiguration(LocationMode.COMPASS,true,mIconLocation);
//設(shè)置定位圖層配置信息,只有先允許定位圖層后設(shè)置定位圖層配置信息才會(huì)生效,參見(jiàn) setMyLocationEnabled(boolean)
baidumap.setMyLocationConfiguration(configuration);
baidumap.setMyLocationData(locData);
首先我們看到我們的 .accuracy(0)是修改過(guò)的,這里是控制半徑的顯示,這里設(shè)置0為不顯示,
其次可以看到修改后的代碼主要增加了MyLocationConfiguration,
而我們來(lái)詳細(xì)看一下這個(gè)對(duì)象構(gòu)造方法所接受的3個(gè)參數(shù),第一個(gè)是定位模式,這里主要分為3種模式
LocationMode.FOLLOWING //跟隨:小圓點(diǎn)箭頭顯示方向
LocationMode.NORMAL //默認(rèn):小圓點(diǎn),沒(méi)有方向顯示
LocationMode.COMPASS //羅盤(pán):帶東南西北的虛線(xiàn)圈
我們一般會(huì)選擇羅盤(pán)模式,反正我在實(shí)際生活中使用地圖就覺(jué)得羅盤(pán)模式很方便,哈哈。(老掉向啦!)
第二個(gè)參數(shù)是我們?cè)O(shè)置是否允許顯示方向,true的話(huà)是允許,然后我們就可以看到方向,但是還不要著急,這里面有大文章呢。
第三個(gè)是一個(gè)圖標(biāo)配置,我這里用了下面這張圖
這個(gè)常見(jiàn)的定位圖標(biāo)。當(dāng)然如果我們傳入null,也是會(huì)顯示這個(gè)圖標(biāo)的,只不過(guò)是百度帶的
這里我們看到我們的效果是這個(gè)樣紙滴。(分辨率還可以,我是把他放在xhdpi文件夾里的)
那么我們?cè)賮?lái)討論一下這個(gè)方向的問(wèn)題。
細(xì)心的讀者可能已經(jīng)看到 .direction(bdLocation.getDirection())代碼上面的注釋了,開(kāi)發(fā)者設(shè)置獲取到的方向信息,那么這句話(huà)的意思是什么?我們不是已經(jīng)給了bdLocation.getDirection()了么?
如果有跟著我們一步一步坐下來(lái)的可能就會(huì)發(fā)現(xiàn),我們的圖標(biāo)根本不會(huì)隨著方向動(dòng),就算不寫(xiě)在if條件里面也不會(huì)。確實(shí)是這樣的。
因?yàn)槲覀僢dLocation.getDirection()是有要求的,那就是option,我們要給他允許,他才能獲取方向。
option.setNeedDeviceDirect(true); //需要設(shè)備方向
當(dāng)你設(shè)置這一句之后(注意暫時(shí)把定位圖層代碼移到if語(yǔ)句外面,我們要看本次的運(yùn)行結(jié)果),你再運(yùn)行發(fā)現(xiàn),一卡一卡的。 確實(shí)因?yàn)槟阍O(shè)置的定位時(shí)間span,導(dǎo)致它一卡一卡不能實(shí)時(shí)獲取方向信息,那我們能怎么解決這個(gè)問(wèn)題呢?
答案是利用手機(jī)自帶的方向傳感器。
2017年8月2日13:45:27 繼續(xù)更新
昨天陸陸續(xù)續(xù)的遇到一些小問(wèn)題,不過(guò)現(xiàn)在已經(jīng)陸續(xù)解決了,由于我也是邊學(xué)邊寫(xiě),所以有什么問(wèn)題還請(qǐng)大神多多指教。
那么我們回到正題,我們?cè)趺床拍茏尠俣鹊貓D和手機(jī)傳感器結(jié)合到一起呢?
首先肯定是我們的傳感信息獲取,這部分代碼是參考鴻洋大神在慕課視頻寫(xiě)的,在這里面我們提供了一個(gè)start方法和一個(gè)stop方法,分別控制傳感器的啟動(dòng)和結(jié)束,在啟動(dòng)方法里我們主要是獲取方向傳感器并注冊(cè),stop方法主要是解除注冊(cè),在重寫(xiě)的方法里監(jiān)聽(tīng)方向變化,通過(guò)接口來(lái)對(duì)外公布數(shù)據(jù)。
package com.surine.onemap;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* Created by surine on 2017/8/1.
*/
public class MyOrientationListener implements SensorEventListener {
//傳感器管理
private SensorManager mySensorManager;
//傳感器
private Sensor mySensor;
private Context myContext;
//x軸坐標(biāo)
private float lastX;
//監(jiān)聽(tīng)器
private onOrientationListener myOrientationListener;
public void start(){//開(kāi)啟方向傳感器
//先通過(guò)系統(tǒng)服務(wù)來(lái)得到傳感器管理對(duì)象mySensorManager
mySensorManager=(SensorManager) myContext.getSystemService(Context.SENSOR_SERVICE);
if (mySensorManager!=null) {//如果傳感器管理對(duì)象不為空,則可以通過(guò)傳感器管理對(duì)象來(lái)獲得方向傳感器對(duì)象
//獲得方向傳感器對(duì)象
mySensor=mySensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
if (mySensor!=null) {//如果方向傳感器不為空,則給該方向傳感器注冊(cè)監(jiān)聽(tīng)事件
//傳入,監(jiān)聽(tīng)器,傳感器對(duì)象,傳感精度
mySensorManager.registerListener(this, mySensor, SensorManager.SENSOR_DELAY_GAME);
}
}
public void stop(){//解除注冊(cè)方向傳感器監(jiān)聽(tīng)事件
mySensorManager.unregisterListener(this);
}
//構(gòu)造方法
public MyOrientationListener(Context myContext) {//方向傳感器的一個(gè)構(gòu)造器
super();
this.myContext = myContext;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
//監(jiān)聽(tīng)方向發(fā)生變化
@Override
public void onSensorChanged(SensorEvent event) {//精度發(fā)生改變的時(shí)候
if (event.sensor.getType()==Sensor.TYPE_ORIENTATION) {//如果是方向傳感器
float x=event.values[SensorManager.DATA_X];//獲得傳感器的X軸的坐標(biāo),可以返回3個(gè)值,即X軸的坐標(biāo),Y軸坐標(biāo),Z軸坐標(biāo),我們只需要X軸坐標(biāo)
if (Math.abs(x-lastX)>1.0) {//對(duì)比本次的X坐標(biāo)的變化比上一次的變化差大于1.0就說(shuō)明方向發(fā)生改變
if (myOrientationListener!=null) {//說(shuō)明主界面已經(jīng)注冊(cè)了事件,即不為空,然后產(chǎn)生一個(gè)回調(diào)將實(shí)時(shí)變化X軸的坐標(biāo)傳入
//通過(guò)一個(gè)回調(diào)方法,通知主界面去更新UI
myOrientationListener.onOrientationChanged(lastX);//就需要把上一次的X軸坐標(biāo)傳入,在MainActivity中的回調(diào)方法中去獲取即可
}
}
lastX=x;
}
}
public void setMyOrientationListener(onOrientationListener myOrientationListener) {
this.myOrientationListener = myOrientationListener;
}
//寫(xiě)一個(gè)接口實(shí)現(xiàn)方向改變的監(jiān)聽(tīng)產(chǎn)生的回調(diào)
public interface onOrientationListener{
void onOrientationChanged(float x);//回調(diào)的方法
}
}
那么怎么使用呢?
首先我們?cè)谥骰顒?dòng)管理傳感器,
@Override
protected void onStop() {
super.onStop();
···省略代碼
myOrientationListener.stop();
}
@Override
protected void onStart() {
super.onStart();
myOrientationListener.start();
}
我們讓傳感器的啟動(dòng)與停止符合活動(dòng)的周期,然后增加一個(gè)方法來(lái)監(jiān)聽(tīng)傳感數(shù)據(jù)
/**
* 定位結(jié)合方向傳感器,從而可以實(shí)時(shí)監(jiān)測(cè)到X軸坐標(biāo)的變化,從而就可以檢測(cè)到
* 定位圖標(biāo)方向變化,只需要將這個(gè)動(dòng)態(tài)變化的X軸的坐標(biāo)更新myCurrentX值,
* 最后在MyLocationData data.driection(myCurrentX);
* */
private void useLocationOrientationListener() {
myOrientationListener=new MyOrientationListener(MainActivity.this);
myOrientationListener.setMyOrientationListener(new onOrientationListener() {
@Override
public void onOrientationChanged(float x) {//監(jiān)聽(tīng)方向的改變,方向改變時(shí),需要得到地圖上方向圖標(biāo)的位置
//聲明一個(gè)double型的臨時(shí)變量,記錄傳感方向
myCurrentX=x;
}
});
}
這個(gè)方法在初始化client的時(shí)候調(diào)用即可。
最后我們看看拿到的值怎么使用
MyLocationData locData = new MyLocationData.Builder()
.accuracy(0)
// 此處設(shè)置開(kāi)發(fā)者獲取到的方向信息,myCurrentX
.direction(myCurrentX).latitude(lati_)
.longitude(long_).build();
baidumap.setMyLocationData(locData);
可以看到,這樣我們的傳感器就和地圖結(jié)合起來(lái)了,我們趕緊來(lái)運(yùn)行一下。
咦?怎么一卡一卡的?
是我手機(jī)配置不行么?可是我看人家百度地圖好好的啊,非常順暢。
卡就對(duì)了,而且還會(huì)根據(jù)span的周期卡頓呢!
我這么一說(shuō)你可能明白點(diǎn)什么,我們把MyLocationData 這一段代碼寫(xiě)在了moveTo方法里了,而這段代碼是誰(shuí)調(diào)用的,答案就是位置監(jiān)聽(tīng)器LocationListener,而我們之前說(shuō)過(guò),為了節(jié)省電量,這個(gè)類(lèi)的接收函數(shù)不會(huì)一直運(yùn)行,而是根據(jù)span間隔運(yùn)行,而span最低數(shù)為1000,也就是一秒,所以你的方向也會(huì)跟著一秒卡一下一秒卡一下,那么這樣我們也就知道這段代碼該往哪里寫(xiě)了,
當(dāng)然是方向傳感器的監(jiān)聽(tīng)器里面啦,老鐵!
此時(shí)我們的代碼變成了這樣,
private void useLocationOrientationListener() {
myOrientationListener=new MyOrientationListener(MainActivity.this);
myOrientationListener.setMyOrientationListener(new onOrientationListener() {
@Override
public void onOrientationChanged(float x) {//監(jiān)聽(tīng)方向的改變,方向改變時(shí),需要得到地圖上方向圖標(biāo)的位置
myCurrentX=x;
MyLocationData locData = new MyLocationData.Builder()
.accuracy(0)
// 此處設(shè)置開(kāi)發(fā)者獲取到的方向信息
.direction(myCurrentX).latitude(lati_)
.longitude(long_).build();
baidumap.setMyLocationData(locData);
}
});
}
再次運(yùn)行,哇哦,那絲滑……簡(jiǎn)直不敢想象,想要更明顯的看到,切換到羅盤(pán)模式看看效果。
可以說(shuō)到這,我們已經(jīng)實(shí)現(xiàn)了方向的顯示,下面是一段小插曲。
過(guò)場(chǎng)休息……
我們也玩了這么久的百度地圖了,也遇到不少問(wèn)題,我覺(jué)得頭頭都要大了(努力賣(mài)萌,喵~),我們不如做一點(diǎn)放松的事情,美化一下界面。
嗯哼,還是有點(diǎn)百度地圖的意思,不過(guò)咱這個(gè)更Material Design一點(diǎn),可以看出狀態(tài)欄的效果,頂部欄的效果,都是朝著MD的感覺(jué)走的,那么我們看看源代碼。
我這里是在Android Studio里面直接使用了抽屜那個(gè)界面的模板
它在這里是分文件寫(xiě)的。
【文件:content_main.xml】
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.surine.onemap.MainActivity"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.baidu.mapapi.map.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
/>
<TextView
android:id="@+id/first"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="Hello World!"
android:visibility="gone"
/>
<ImageView
android:id="@+id/my_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="30dp"
android:layout_marginLeft="30dp"
android:elevation="5dp"
android:background="@drawable/circle_shape"
android:padding="10dp"
android:src="@drawable/main_icon_location" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_marginTop="32dp"
android:layout_width="match_parent"
android:layout_height="52dp"
android:background="#fff"
android:elevation="4dp"
app:titleMargin="5dp"
app:theme="@style/ToolbarTheme"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</RelativeLayout>
【文件:activty_main.xml】
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include layout="@layout/content_main"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
之所以都貼上來(lái)是為了讓大家看看有一些屬性的配置,比如說(shuō)android:fitsSystemWindows可能影響透明化狀態(tài)欄的顯示
那么我們的透明化狀態(tài)欄還需要的操作就是在activity里面配置
setContentView(R.layout.activity_main);
//在 setContentView(R.layout.activity_main);后面開(kāi)始寫(xiě)
在SDK21上的效果,這里我們只兼容Android5.0以上
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
//經(jīng)測(cè)試發(fā)現(xiàn) 半透明 #50000000 顏色比較符合規(guī)范
getWindow().setStatusBarColor(Color.parseColor("#50000000"));
}
接下來(lái)我們調(diào)整一下toolbar的標(biāo)題顏色
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//給一個(gè)淺一點(diǎn)的灰色
toolbar.setTitleTextColor(getResources().getColor(R.color.text));
好了,上面已經(jīng)差不多了,我們看看下面,可以看到我們這里有一個(gè)按鈕,相信大家也已經(jīng)猜到了,這個(gè)就是用來(lái)手動(dòng)定位的,我們?cè)谒谋O(jiān)聽(tīng)器里寫(xiě)定位邏輯就OK
具體的方法寫(xiě)在下面了,這個(gè)方法在我們的onCreate()里調(diào)用即可
好現(xiàn)在我們分析一下代碼。
- 行1:findviewbyid,沒(méi)啥好說(shuō)的
- 行2:設(shè)置監(jiān)聽(tīng),也是很常見(jiàn)的寫(xiě)法
- switch:在onclick方法里面有這么一個(gè)switch語(yǔ)句,這個(gè)主要是給我們的按鈕增加了一個(gè)多用的功能,點(diǎn)擊切換定位模式,首先我們的mCurrentMode默認(rèn)值為L(zhǎng)ocation.NORMAL,然后點(diǎn)擊事件根據(jù)當(dāng)前的mCurrentMode切換
- case :我們分析其中一個(gè)case選項(xiàng),首先是定位賦值,這個(gè)必須的,因?yàn)槲覀円淖兌ㄎ荒J剑x值之后開(kāi)始真正設(shè)置定位模式
然后我們調(diào)整地圖角度,這個(gè)也是模仿百度地圖等做的,根據(jù)當(dāng)前方向調(diào)整角度,使用了rotate方法和overlook方法,然后加一個(gè)zoom縮放,使用animateMapStatus更新地圖view
這里還有一個(gè)設(shè)置圖標(biāo)的方法,主要是為了區(qū)分兩種定位模式,我做了一個(gè)藍(lán)色一個(gè)灰色的圖標(biāo),來(lái)互相切換
private void MyLocationButton() {
location_icon = (ImageView) findViewById(R.id.my_location);
location_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (mCurrentMode) {
case NORMAL:
//定位模式賦值
mCurrentMode = LocationMode.COMPASS;
//配置定位模式
baidumap.setMyLocationConfiguration(new MyLocationConfiguration(
mCurrentMode, true, mCurrentMarker));
//調(diào)整地圖角度,設(shè)置圖標(biāo)
location_icon.setImageResource(R.drawable.main_icon_location_compass);
MapStatus.Builder builder = new MapStatus.Builder();
builder.rotate(myCurrentX).overlook(0).zoom(18f);
baidumap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
break;
case COMPASS:
mCurrentMode = LocationMode.NORMAL;
baidumap.setMyLocationConfiguration(new MyLocationConfiguration(
mCurrentMode, true, mCurrentMarker));
MapStatus.Builder builder1 = new MapStatus.Builder();
location_icon.setImageResource(R.drawable.main_icon_location);
builder1.rotate(0).overlook(0).zoom(18f);
baidumap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder1.build()));
break;
default:
break;
}
}
});
}
這里我再貼一下moveto的代碼,梳理一下邏輯
//地圖控制方法
private void moveTo(final BDLocation bdLocation) {
lati_ = bdLocation.getLatitude();
long_ = bdLocation.getLongitude();
mCurrentAccracy = bdLocation.getRadius();
//默認(rèn)配置
baidumap.setMyLocationConfiguration(new MyLocationConfiguration(
mCurrentMode, true, mCurrentMarker));
if(isFirstLocate){
isFirstLocate = false;
baidumap.setMyLocationConfiguration(new MyLocationConfiguration(
mCurrentMode, true, null));
LatLng ll = new LatLng(lati_,long_);
update = MapStatusUpdateFactory.newLatLng(ll);
baidumap.animateMapStatus(update);
new Thread(new Runnable() {
@Override
public void run() {
try {
//延時(shí)動(dòng)畫(huà)縮放
Thread.sleep(300);
update = MapStatusUpdateFactory.zoomTo(18f);
baidumap.animateMapStatus(update);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
這些代碼大家都已經(jīng)見(jiàn)到過(guò),沒(méi)啥新奇的東西,
最后我們的監(jiān)聽(tīng)器也修改了一下,主要去掉了第一篇文章的文字顯示,加上一些防空判斷,和settitle設(shè)置一些toolbar上顯示的文字
//接受位置信息
@Override
public void onReceiveLocation(final BDLocation bdLocation) {
// map view 銷(xiāo)毀后不在處理新接收的位置
if (bdLocation == null || mmap == null) {
return;
}
baidumap.clear();
//調(diào)用設(shè)置方法
moveTo(bdLocation);
runOnUiThread(new Runnable() {
@Override
public void run() {
if(!bdLocation.getLocationDescribe().equals("")){
setTitle(bdLocation.getLocationDescribe());
}else{
setTitle(R.string.app_name);
}
}
});
}
到此為止我們已經(jīng)實(shí)現(xiàn)了自動(dòng)定位,手動(dòng)定位。那么接下來(lái)我們繼續(xù)回到SDK。
地圖子控件處理
我們可以看到在我們的地圖上有很多其他的東西,比如說(shuō)標(biāo)尺,百度LOGO,縮放控件,羅盤(pán),等等等等,其實(shí)這些東西都可以拿來(lái)修改處理,于是乎我單獨(dú)寫(xiě)了這么一個(gè)方法來(lái)處理這些元素,讓界面變得更加整潔。
在初始化地圖的時(shí)候,調(diào)用這個(gè)方法,可以看到我們隱藏了比例尺,縮放控件,百度logo,調(diào)整了羅盤(pán)位置
private void changeDefaultBaiduMapView(MapView mmap) {
// 隱藏地圖上比例尺
mmap.showScaleControl(false);
// 隱藏地圖縮放控件
mmap.showZoomControls(false);
//羅盤(pán)位置
baidumap.setCompassPosition(new Point(70,250));
// 隱藏百度的LOGO
View child = this.mmap.getChildAt(1);
//原理也就是在view里面找到一個(gè)iamgeview(也就是logo),然后隱藏
if (child != null && (child instanceof ImageView)) {
child.setVisibility(View.INVISIBLE);
}
}
我們打算實(shí)現(xiàn)一個(gè)自定義的縮放控件,首先看一下我們修改的布局文件,我們這里省略了一些代碼(注意toolbar一定要放在最后面,因?yàn)樗莦軸上離我們最近的,防止被mapview覆蓋)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.surine.onemap.MainActivity"
xmlns:android="http://schemas.android.com/apk/res/android">
···· 省略的代碼
<RelativeLayout
android:id="@+id/ZoomControlView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#fff"
android:elevation="2dp"
android:layout_marginRight="5.0dip"
android:layout_centerVertical="true"
android:layout_alignEnd="@+id/toolbar">
<Button
android:id="@+id/zoomin"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="40dip"
android:layout_height="45dip"
android:textSize="18sp"
android:text="+"/>
<Button
android:id="@+id/zoomout"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="40dip"
android:layout_height="45dip"
android:textSize="18sp"
android:layout_below="@+id/zoomin"
android:text="-"/>
</RelativeLayout>
···省略代碼
</RelativeLayout>
可以看到這里是兩個(gè)按鈕組成的一個(gè)縮放控件,那么他們的監(jiān)聽(tīng)器實(shí)現(xiàn)如下
private void MyZoomControl() {
zoomInBtn = (Button) findViewById(R.id.zoomin);
zoomOutBtn = (Button) findViewById(R.id.zoomout);
zoomInBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
float zoomLevel = baidumap.getMapStatus().zoom;
if(zoomLevel<=18){
baidumap.animateMapStatus(MapStatusUpdateFactory.zoomIn());
zoomOutBtn.setEnabled(true);
}else{
Toast.makeText(MainActivity.this, "已經(jīng)放至最大!", Toast.LENGTH_SHORT).show();
zoomInBtn.setEnabled(false);
}
}
});
zoomOutBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
float zoomLevel = baidumap.getMapStatus().zoom;
if(zoomLevel>4){
baidumap.animateMapStatus(MapStatusUpdateFactory.zoomOut());
zoomInBtn.setEnabled(true);
}else{
zoomOutBtn.setEnabled(false);
Toast.makeText(MainActivity.this, "已經(jīng)縮至最小!", Toast.LENGTH_SHORT).show();
}
}
});
}
控制縮放的代碼大家也見(jiàn)到過(guò),在第二篇文章,這里的代碼和 那里的沒(méi)什么兩樣,主要是增加了一些button的UI控制,禁止點(diǎn)擊啊之類(lèi)的。
好,那我們的界面最終成了什么樣子呢?
可以說(shuō),不比百度地圖差吧。
總結(jié)
那么這篇文章到這里也就算結(jié)束了吧,這篇文章講的東西比較少,主要是在界面上做一些優(yōu)化,那么下一篇文章我們會(huì)討論點(diǎn)啥呢?
期待嗎?
參考
hyman csdn博客
hyman mooc視頻
簡(jiǎn)書(shū):zhh_happig
baidumapdemo