专栏首页跟牛老师一起学WEBGIS用百度地图API打造方便自己使用的手机地图

用百度地图API打造方便自己使用的手机地图

有钱人咱就不说了,因为偶是个穷银……因为穷,所以去年买的Huawei C8650+到现在还在上岗,对于没有钱买好的配置的手机的童鞋来说,类似于百度,谷歌,高德等商家的地图在自己的机器上跑起来确实是有点勉为其难,为了能够用上手机的地图,并不怎么大,最近闲来无事,就动起了这方面的脑筋,结果就是用百度地图API开发一个自己想要的功能的地图……

这是经过一点时间倒腾后的一点点小成果,实现了自定义的放大缩小按钮,GPS定位,GPS当前位置500m范围内关键字的搜索。下面这张截图说明了上面提到的几个功能,其中我的搜索关键字为“公交”……

嗯,看完效果说说我的具体实现吧。下图为工程的目录结构:

源代码如下:

MainActivity.java

package com.lzugis.mymap;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.graphics.Bitmap;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKBusLineResult;
import com.baidu.mapapi.search.MKDrivingRouteResult;
import com.baidu.mapapi.search.MKPoiResult;
import com.baidu.mapapi.search.MKSearchListener;
import com.baidu.mapapi.search.MKShareUrlResult;
import com.baidu.mapapi.search.MKSuggestionResult;
import com.baidu.mapapi.search.MKTransitRouteResult;
import com.baidu.mapapi.search.MKWalkingRouteResult;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.PoiOverlay;
import com.baidu.mapapi.map.PopupClickListener;
import com.baidu.mapapi.map.PopupOverlay;
import com.baidu.platform.comapi.basestruct.GeoPoint;

import com.lzugis.myview.SearchControlView;
import com.lzugis.myview.ZoomControlView;
import com.org.baidumap.R;

public class MainActivity extends Activity 
{
	 //地图显示
	 private BMapManager mBMapMan = null;
	 private MapView mMapView = null;
	 private MapController mMapController = null;
	 
	 //提示信息
	 private Toast toast;
	 //获取当前位置
	 private Button currentloc;	
	 //Poi查询
	 
	 //定位SDK的核心类
	 private LocationClient mLocClient;
	 //用户位置信息 
	 private LocationData mLocData;
	 //我的位置图层
	 private LocationOverlay myLocationOverlay = null;
	 //弹出窗口图层
	 private PopupOverlay mPopupOverlay  = null;
	 //是否手动触发请求定位	
	 private boolean isRequest = false;
	 //是否首次定位
	 private boolean isFirstLoc = true;
	 //POI搜索
	 private MKSearch mMKSearch;
	 
	 //放大缩小控件
	 private ZoomControlView mZoomControlView;
	 //搜索控件
	 private SearchControlView mSearchControlView;
	 
		
	 @Override
     public void onCreate(Bundle savedInstanceState)
	 {
		 super.onCreate(savedInstanceState);
		 mBMapMan=new BMapManager(getApplication());
		 //开发授权码
		 String strKey="wNdy48s7V1izbLL0ziswArXq";
		 mBMapMan.init(strKey, new MKGeneralListenerImpl());  
		 //注意:请在试用setContentView前初始化BMapManager对象,否则会报错
		 setContentView(R.layout.main);		
		 mMapView=(MapView)findViewById(R.id.bmapsView);
		 //不显示内置缩放控件
		 mMapView.setBuiltInZoomControls(false);
		 //设置交通信息图可见
		 mMapView.setTraffic(true);  
		 //得到mMapView的控制权,可以用它控制和驱动平移和缩放
		 mMapController=mMapView.getController();
		 //用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6)
		 GeoPoint point =new GeoPoint((int)(40.805* 1E6),(int)(111.661* 1E6));
		 //设置地图中心点
		 mMapController.setCenter(point);
		 //设置地图zoom级别
		 mMapController.setZoom(12);	
		 
		 //用户自定义放大缩小控件初始化
		 mZoomControlView = (ZoomControlView) findViewById(R.id.ZoomControlView);
		 mZoomControlView.setMapView(mMapView);
		 //用户自定义搜索控件初始化
		 mMKSearch = new MKSearch();
		 mMKSearch.init(mBMapMan, new MySearchListener());
		 mSearchControlView=(SearchControlView)findViewById(R.id.SearchControlView);
		 mSearchControlView.setMapView(mMapView);
		 mSearchControlView.setMapController(mMapController);
		 mSearchControlView.setMKSearch(mMKSearch);
		 
		//地图显示事件监听器。 该接口监听地图显示事件,用户需要实现该接口以处理相应事件。
		mMapView.regMapViewListener(mBMapMan, new MKMapViewListener() 
		{			
			@Override
			//地图移动结束时
			public void onMapMoveFinish() 
			{					 
				refreshZoomControl();				
			}				
				
			@Override	
			//地图加载结束时
			public void onMapLoadFinish() 
			{					
				
			}
				
			@Override				
			public void onMapAnimationFinish() 
			{					 
				refreshZoomControl();				
			}				
				
			@Override				
			public void onGetCurrentMap(Bitmap arg0) 
			{					
				
			}				
				
			@Override				
			public void onClickMapPoi(MapPoi arg0) 
			{					
				
			}			
		});		 
		 
		//实例化弹出窗口图层	     
		mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() 	     
		{      
	    	 /**	        
	    	  * 点击弹出窗口图层回调的方法	        
	         */			
	    	 @Override	    	 
	    	 public void onClickedPopup(int arg0) 	    	 
	    	 { 
	    		 //隐藏弹出窗口图层		
	    		 mPopupOverlay.hidePop();		
	    	 }		 
		});
	     
	    mLocClient = new LocationClient(getApplicationContext());		
	    mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口			
			
	    /**
		 * LocationClientOption 该类用来设置定位SDK的定位方式。
	    */			
	    LocationClientOption option = new LocationClientOption();			
	    option.setOpenGps(true); //打开GPRS			
	    option.setAddrType("all");//返回的定位结果包含地址信息			
	    option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02			
	    option.setPriority(LocationClientOption.GpsFirst); // 设置GPS优先			
	    option.setScanSpan(5000); //设置发起定位请求的间隔时间为5s	
	    option.disableCache(true);//启用缓存定位			
	    mLocClient.setLocOption(option);  //设置定位参数			
	    	
	    //定位图层初始化			
	    myLocationOverlay = new LocationOverlay(mMapView);							
	    //实例化定位数据,并设置在我的位置图层	        
	    mLocData = new LocationData();		    
	    myLocationOverlay.setData(mLocData);	    		    
	    //添加定位图层		    
	    mMapView.getOverlays().add(myLocationOverlay);        
	    //修改定位数据后刷新图层生效		    
	    mMapView.refresh();
		 
		toast = Toast.makeText(getApplicationContext(),
					"", Toast.LENGTH_LONG);		 
		currentloc=(Button)findViewById(R.id.currentloc);
		currentloc.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) 
			{	
				mLocClient.start();  //调用此方法开始定位
				requestLocation();			
			}		 
		});
		 
		toast.setText(R.string.load_message);
		toast.setGravity(Gravity.CENTER, 0, 0);
		toast.show();
     }

	private void refreshZoomControl()
	{	   
		//更新缩放按钮的状态	        
		mZoomControlView.refreshZoomButtonStatus(Math.round(mMapView.getZoomLevel()));
	}		
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch(item.getItemId())
		{
			case R.id.menu_settings:
			{
				toast.setText("软件设置");
			    toast.setGravity(Gravity.BOTTOM, 0, 0);
			    toast.show();	
			    break;
			}
			default:
			{
				exitAlert("真的要退出我的地图吗?");
				break;
			}
		}
		return true;
	}
	
	private void exitAlert(String msg)
	{
		//实例化
		AlertDialog.Builder builder=new AlertDialog.Builder(this);
		builder.setMessage(msg)
			.setCancelable(false)
			.setPositiveButton("确定", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					finish();
				}
			})
			.setNegativeButton("取消", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					return;
				}
			});
		AlertDialog alert=builder.create();
		alert.show();
	}

	@Override
	protected void onResume() 
	{
    	//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
		mMapView.onResume();
		super.onResume();
	}

	@Override
	protected void onPause() 
	{
		//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
		mMapView.onPause();
		super.onPause();
	}

	@Override
	protected void onDestroy() 
	{
		//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
		mMapView.destroy();
		
		//退出应用调用BMapManager的destroy()方法
		if(mBMapMan != null)
		{
			mBMapMan.destroy();
			mBMapMan = null;
		}
		
		//退出时销毁定位
        if (mLocClient != null)
        {
            mLocClient.stop();
        }
		
		super.onDestroy();
	}
	/**
	 * 
	 * @author lzugis
	 *
	 */
	public class BDLocationListenerImpl implements BDLocationListener 
	{
		/**
		 * 接收异步返回的定位结果,参数是BDLocation类型参数
		 */
		@Override
		public void onReceiveLocation(BDLocation location) 
		{
			//设置location
			mSearchControlView.setBDLocation(location);
			
			if (location == null) 
			{
				return;
			}
			
		    StringBuffer sb = new StringBuffer(256);
		      sb.append("time : ");
		      sb.append(location.getTime());
		      sb.append("\nerror code : ");
		      sb.append(location.getLocType());
		      sb.append("\nlatitude : ");
		      sb.append(location.getLatitude());
		      sb.append("\nlontitude : ");
		      sb.append(location.getLongitude());
		      sb.append("\nradius : ");
		      sb.append(location.getRadius());
		      if (location.getLocType() == BDLocation.TypeGpsLocation)
		      {
		          sb.append("\nspeed : ");
		          sb.append(location.getSpeed());
		          sb.append("\nsatellite : ");
		          sb.append(location.getSatelliteNumber());
		           
		      } 
		      else if (location.getLocType() == BDLocation.TypeNetWorkLocation)
		      {
		    	  sb.append("\naddr : ");
		          sb.append(location.getAddrStr());
		        
		      } 
		 
		      Log.e("log", sb.toString());			
			
			mLocData.latitude = location.getLatitude();
			mLocData.longitude = location.getLongitude();
			//如果不显示定位精度圈,将accuracy赋值为0即可
			mLocData.accuracy = location.getRadius();
			mLocData.direction = location.getDerect();
			
			//将定位数据设置到定位图层里
            myLocationOverlay.setData(mLocData);
            //更新图层数据执行刷新后生效
            mMapView.refresh();            
			
            if(isFirstLoc || isRequest)
            {
            	//将给定的位置点以动画形式移动至地图中心
				mMapController.animateTo(new GeoPoint(
						(int) (location.getLatitude() * 1e6), (int) (location
								.getLongitude() * 1e6)));
				isRequest = false;
            }
            isFirstLoc = false;           
		}

		/**
		 * 接收异步返回的POI查询结果,参数是BDLocation类型参数
		 */
		@Override
		public void onReceivePoi(BDLocation poiLocation) 
		{
			
		}
	}
	/**
	 * 
	 * @author lzugis
	 *
	 */
	private class LocationOverlay extends MyLocationOverlay
	{

		public LocationOverlay(MapView arg0) 
		{
			super(arg0);
		}
		
		/**
		 * 在“我的位置”坐标上处理点击事件。
		 */
		@Override
		protected boolean dispatchTap() 
		{
			//点击我的位置显示PopupOverlay
			return super.dispatchTap();
		}
		
	}	
	/**
	 * 
	 * @author lzugis
	 *
	 */
	public void requestLocation() 
	{
		isRequest = true;		
		if(mLocClient != null && mLocClient.isStarted())
		{
			showToast("GPS正在定位……");
			mLocClient.requestLocation();
		}
		else
		{
			Log.d("log", "locClient is null or not started");
		}
	}
	/**
	 * 
	 * @author lzugis
	 *
	 */
	private void showToast(String msg)
	{  
        if(toast == null)
        {  
        	toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);  
        }
        else
        {  
        	toast.setText(msg);  
        	toast.setDuration(Toast.LENGTH_SHORT);
        }  
        toast.show();  
    } 
	/**
	 * 
	 * @author lzugis
	 *
	 */
	public class MKGeneralListenerImpl implements MKGeneralListener
	{
		/**
		 * 一些网络状态的错误处理回调函数
		 */
		@Override
		public void onGetNetworkState(int iError) 
		{
			if (iError == MKEvent.ERROR_NETWORK_CONNECT) 
			{
				showToast("您的网络出错啦!");
            }
		}

		/**
		 * 授权错误的时候调用的回调函数
		 */
		@Override
		public void onGetPermissionState(int iError) 
		{
			if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) 
			{
				showToast("API KEY错误, 请检查!");
            }
		}		
	}
	
	public class MySearchListener implements MKSearchListener {
		
		@Override
		public void onGetAddrResult(MKAddrInfo result, int iError) {
		}

		
		@Override
		public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
		}

		
		@Override
		public void onGetPoiResult(MKPoiResult result, int type, int iError) {
			if (result == null) {
				return;
			}
			//
			PoiOverlay poioverlay = new PoiOverlay(MainActivity.this, mMapView);
			//
			poioverlay.setData(result.getAllPoi());
			//
			mMapView.getOverlays().add(poioverlay);
		}


		@Override
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}


		@Override
		public void onGetPoiDetailSearchResult(int arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}


		@Override
		public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1,
				int arg2) {
			// TODO Auto-generated method stub
			
		}


		@Override
		public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}


		@Override
		public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}


		@Override
		public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {
			// TODO Auto-generated method stub
			
		}
	}
}

SearchControlView.java

package com.lzugis.myview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;

import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.org.baidumap.R;

public class SearchControlView  extends RelativeLayout implements OnClickListener
{
	private MapView mapView;
	private MKSearch mMKSearch;
	private BDLocation location;
	private MapController mMapController;
	
	private EditText txtSearch;
	private Button mButtonSearch;
	
	public SearchControlView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SearchControlView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}
	
	private void init() 
	{
		View view = LayoutInflater.from(getContext()).inflate(R.layout.search_controls_layout, null);
		txtSearch=(EditText)view.findViewById(R.id.edittextSearch);
		mButtonSearch = (Button) view.findViewById(R.id.search);
		mButtonSearch.setOnClickListener(this);
		addView(view);
	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		if(mapView == null)
		{
			throw new NullPointerException("you can call setMapView(MapView mapView) at first");
		}
		GeoPoint geoPoint = new GeoPoint((int) (location.getLatitude() * 1e6),
				(int) (location.getLongitude() * 1e6));
		mapView.getController().animateTo(geoPoint);
		String strSearch=txtSearch.getText().toString();
		mMKSearch.poiSearchNearBy(strSearch, geoPoint, 500);
		//设置地图中心点
		 mMapController.setCenter(geoPoint);
		 //设置地图zoom级别
		 mMapController.setZoom(16);
	}
	
	/**
	 * 与MapView设置关联
	 * @param mapView
	 */
	public void setMapView(MapView mapView) 
	{
		this.mapView = mapView;
	}
	
	public void setBDLocation(BDLocation location) 
	{
		this.location = location;
	}
	
	public void setMKSearch(MKSearch mMKSearch) 
	{
		this.mMKSearch = mMKSearch;
	}
	
	public void setMapController(MapController mMapController) 
	{
		this.mMapController = mMapController;
	}
}

ZoomControlView.java

package com.lzugis.myview;

import com.baidu.mapapi.map.MapView;
import com.org.baidumap.R;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.view.View.OnClickListener;

public class ZoomControlView extends RelativeLayout implements OnClickListener{
	private Button mButtonZoomin;
	private Button mButtonZoomout;
	private MapView mapView;
	private int maxZoomLevel;
	private int minZoomLevel;
	
	public ZoomControlView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public ZoomControlView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	
	private void init() {
		View view = LayoutInflater.from(getContext()).inflate(R.layout.zoom_controls_layout, null);
		mButtonZoomin = (Button) view.findViewById(R.id.zoomin);
		mButtonZoomout = (Button) view.findViewById(R.id.zoomout);
		mButtonZoomin.setOnClickListener(this);
		mButtonZoomout.setOnClickListener(this);
		addView(view);
	}

	@Override
	public void onClick(View v) {
		if(mapView == null){
			throw new NullPointerException("you can call setMapView(MapView mapView) at first");
		}
		switch (v.getId()) {
		case R.id.zoomin:{
			mapView.getController().zoomIn();
			break;
		}
		case R.id.zoomout:{
			mapView.getController().zoomOut();
			break;
		}
		}
	}

	/**
	 * 与MapView设置关联
	 * @param mapView
	 */
	public void setMapView(MapView mapView) {
		this.mapView = mapView;
		// 获取最大的缩放级别
		maxZoomLevel = mapView.getMaxZoomLevel();
		// 获取最大的缩放级别
		minZoomLevel = mapView.getMinZoomLevel();
	}
	
	
	/**
	 * 根据MapView的缩放级别更新缩放按钮的状态,当达到最大缩放级别,设置mButtonZoomin
	 * 为不能点击,反之设置mButtonZoomout
	 * @param level
	 */
	public void refreshZoomButtonStatus(int level){
		if(mapView == null){
			throw new NullPointerException("you can call setMapView(MapView mapView) at first");
		}
		if(level > minZoomLevel && level < maxZoomLevel){
			if(!mButtonZoomout.isEnabled()){
				mButtonZoomout.setEnabled(true);
			}
			if(!mButtonZoomin.isEnabled()){ 
				mButtonZoomin.setEnabled(true);
			}
		}
		else if(level == minZoomLevel ){
			mButtonZoomout.setEnabled(false);
		}
		else if(level == maxZoomLevel){
			mButtonZoomin.setEnabled(false);
		}
	}

}

location_selector.xml

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/location_press"></item>
    <item android:drawable="@drawable/location_normal"></item>
</selector>

search_selector.xml

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/search_press"></item>
    <item android:drawable="@drawable/search_normal"></item>
</selector>

zoomin_seletor.xml

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/zoomin_press"></item>
    <item android:state_enabled="false" android:drawable="@drawable/zoomin_disable"></item>
    <item android:drawable="@drawable/zoomin_normal"></item>
</selector>

zoomout_seletor.xml

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/zoomout_press"></item>
    <item android:state_enabled="false" android:drawable="@drawable/zoomout_disable"></item>
    <item android:drawable="@drawable/zoomout_normal"></item>
</selector>

layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.baidu.mapapi.map.MapView 
       android:id="@+id/bmapsView"
	   android:layout_width="fill_parent"
	   android:layout_height="fill_parent"
	   android:clickable="true" />  
	   
    <com.lzugis.myview.ZoomControlView
        android:id="@+id/ZoomControlView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="15.0dip"
        android:layout_marginRight="15.0dip"/>
    
    <com.lzugis.myview.SearchControlView
        android:id="@+id/SearchControlView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="15.0dip"/>
    
     <Button
         android:id="@+id/currentloc"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentBottom="true"
         android:layout_marginLeft="15.0dip"
         android:layout_marginBottom="50.0dip"
         android:background="@drawable/location_selector"  />

</RelativeLayout>

search_controls_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <EditText
        android:id="@+id/edittextSearch"
        android:layout_width="fill_parent"
        android:layout_height="49dip"
        android:ems="10" >    
    </EditText>
    <Button
        android:id="@+id/search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_marginTop="3.0dip"
        android:layout_marginRight="3.0dip"
        android:background="@drawable/search_selector"  />

</RelativeLayout>

zoom_controls_layout.xml

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_alignWithParentIfMissing="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/zoomin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/zoomin_seletor" />

    <Button
        android:id="@+id/zoomout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/zoomin"
        android:background="@drawable/zoomout_seletor" />
</RelativeLayout>

menu/main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
     <item
        android:id="@+id/menu_settings"
        android:icon="@drawable/setting"
        android:orderInCategory="100"
        android:title="设置"/>
    
    <item
        android:id="@+id/menu_exit"
        android:icon="@drawable/exit"
        android:orderInCategory="101"
        android:title="退出"/>

</menu>

附件:

源代码

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 安卓中的数据存取

    在我们每天使用的手机设备中,无时无刻都在进行着数据的存和取。安卓作为一种手机操作系统,提供了如下方式的数据存取方式:Preference,File,Sqlite...

    lzugis
  • Android Layput布局

    一个Android视图有很多控件,那么怎么来控制它们的位置排列呢?我们需要容器来存放这些控件并控制它们的位置排列,就像HTML中div,table一样,Andr...

    lzugis
  • Android数据读取之Sqlite数据库操作

    咱们书接上文,继续来说说Android数据读取,这回,我们要讲的是Sqlite数据库的相关操作。以一个实例开始吧:

    lzugis
  • Android的Fragment的第一种声明方式

    Dream城堡
  • Android 使用自定义RecyclerView控件实现Gallery效果

    上篇文章给大家介绍了Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果。其实制作横向滚动的不得不说另一个控件,就...

    砸漏
  • 手把手教你写《雷神》游戏(四)

    游戏排名界面就一个listview 同时我为每个item自定义了view ranklist.xml

    提莫队长
  • SwipeRefreshLayout下拉刷新组件

    在实际开发中,经常都会遇到下拉刷新、上拉加载更多的情形,这一期就一起来学习Android系统的SwipeRefreshLayout下拉刷新组件。 一、...

    分享达人秀
  • Android实现快递单号查询快递状态信息

    今天介绍一个自己做的快递单号查询的简单APP,供大家参考。由于需要使用http和json,本文在build.gradle(module:app)添加了okhtt...

    砸漏
  • android 中ProgressDialog实现全屏效果的示例

    做项目的时候,直接用到了一个ProgressDialog,需要实现全屏的效果,如下图所示,功能跑起来的时候发现不是全屏,只是包裹了当前的内容,如下图所示,不过查...

    砸漏
  • 关于Android短信验证码的获取的示例

    最近突然想起App里面的登录模块,有可以使用手机号码注册的功能,感觉此功能在大多款App里面都比较常见,因此在此做一个记录,顺便将之前踩过得坑在此记录一下,之前...

    砸漏

扫码关注云+社区

领取腾讯云代金券