用百度地图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 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

Android利用V4包中的SwipeRefreshLayout实现上拉加载

基本原理 上拉加载或者说滚动到底部时自动加载,都是通过判断是否滚动到了ListView或者其他View的底部,然后触发相应的操作,这里我们以 ListView来...

3269
来自专栏Android干货

安卓开发_慕课网_百度地图_添加覆盖物

31510
来自专栏Android知识点总结

4-AI--Activity跳转动画

1792
来自专栏青蛙要fly的专栏

Android技能树 — PopupWindow小结

关于下拉选择框,估计大家都有很多选择,我在以前的文章:项目需求讨论-HyBrid模式需求改造 上写过下拉框选择这一块,正好用的Spinner。

1311
来自专栏三好码农的三亩自留地

实现Activity滑动退出

很多应用在二级详情页面加入了滑动退出activity的效果,很方便,心血来潮,想着自己也来实现这个效果,就当做练手吧。

1742
来自专栏分享达人秀

AdapterViewFlipper轻松完成图片轮播

上一期学习了ExpandableListView的使用,你已经掌握了吗?本期开始学习AdapterViewFilpper的使用。 一、认识Adapter...

2575
来自专栏Android小菜鸡

popupWindow的封装与学习

  本篇主要富含了对PopupWindow的封装,实现动画弹窗的例子。可用于相册选择、点赞等等。同时封装使用了建造者模式,对于补间动画的运用同样有较高的学习价值...

1141
来自专栏Android开发指南

3.复杂的viewpager

3909
来自专栏Android干货园

Android自定义组合控件---教你如何自定义下拉刷新和左滑删除

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/80...

1881
来自专栏技术小黑屋

超简单实现Google+列表特效

相信用过Google+的人都感到其应用的特效相当棒,本文将以超简单的形式来实现类似Google+列表的特效。仅仅写几行代码就可以实现奥。

982

扫码关注云+社区

领取腾讯云代金券