简单滑动菜单

刚刚开始学滑动菜单,参考博主jj的android 滑动菜单SlidingMenu的实现

原博客的实现效果(自己的为了简单,UI就没有实现的那么漂亮)

简单滑动菜单_第1张图片

 

以下是学习心得:

(1)XML 讲解 ,先上代码

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


<LinearLayout
    android:id="@+id/my_right"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:layout_marginLeft="80dp"
    >   

    <ListView
        android:id="@+id/my_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
</LinearLayout>    



    
<LinearLayout
        android:id="@+id/my_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/bg_guide_5"/>

</LinearLayout>
 
</RelativeLayout>

 

这个xml的写法也要有要求的,里面定义两个LinearLayout 要滑出显示的菜单的(就是有listview的LinearLayout) 一定要放在上面,不然的话第一个和第二个linearlayout会覆盖层叠的显示出来

 

(2)java代码讲解

1 程序必须实现两个接口,分别是OnGestureListener,OnTouchListener

public class MyTest extends Activity implements OnGestureListener,OnTouchListener{

	private LinearLayout right_layout;	//右边的linearlayout
	
	private LinearLayout left_layout;
	
	private ListView listView;
	
	private int SPEED=30;//菜单显示速度
	
	private int SCREEN_WIDTH;	//手机屏幕的宽度
	
	private int MAX_WIDTH;		//右边linearlayout的宽度
	
	private int mScrollX=0;	//右边菜单偏移坐标
	
	private boolean isScrolling=false;
	
	private GestureDetector gestureDetector;
	
	private String title[] = { "待发送队列", "同步分享设置", "编辑我的资料", "找朋友", "告诉朋友",
			"节省流量", "推送设置", "版本更新", "意见反馈", "积分兑换", "精品应用", "常见问题", "退出当前帐号" };

	
	boolean hasMeasured=false;
	


2 在onCreate方法中去掉activity的标题

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		 
		super.onCreate(savedInstanceState);
		
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.mytest);
		initView();
	}


 

3    initView()方法 初始化部件 设置监听

public void initView(){
		//右边菜单的布局文件
		right_layout=(LinearLayout)findViewById(R.id.my_right);
		
		//左边打开activity显示的布局文件
		left_layout=(LinearLayout)findViewById(R.id.my_left);
		
		//获取屏幕的宽度
		SCREEN_WIDTH=getWindow().getWindowManager().getDefaultDisplay().getWidth();

		System.out.println("SCREEN_WIDTH:"+SCREEN_WIDTH);
	
		listView=(ListView)findViewById(R.id.my_list_view);
		
		//为listview 简单设置数据
		listView.setAdapter(new ArrayAdapter<String>(MyTest.this,
				android.R.layout.simple_list_item_1, 
				title));
		
		gestureDetector=new GestureDetector(this, this);
		 
		//设置touch事件的监听
		left_layout.setOnTouchListener(this);
		right_layout.setOnTouchListener(this);
		
		
		//获取右边 布局(right_layout)文件的宽度
		getMAX_WIDTH();
	
	}


 

4  方法getMAX_WIDTH()获取右边布局(right_layout)的宽,作为左边布局移动的距离

	public void getMAX_WIDTH() {
		ViewTreeObserver viewTreeObserver = left_layout.getViewTreeObserver();
		// 获取控件宽度
		viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
			@Override
			public boolean onPreDraw() {
				if (!hasMeasured) {
					SCREEN_WIDTH = getWindowManager().getDefaultDisplay()
							.getWidth();
					RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) left_layout
							.getLayoutParams();
					layoutParams.width = SCREEN_WIDTH;
					left_layout.setLayoutParams(layoutParams);
					MAX_WIDTH = right_layout.getWidth();
					Log.v("fighter", "MAX_WIDTH=" + MAX_WIDTH + "width="
							+ SCREEN_WIDTH);
					hasMeasured = true;
				}
				return true;
			}
		});

	}	


在这里做下笔记:

函数:

16  /**注册一个回调函数,当一个视图树将要绘制时调用这个回调函数。
17   *参数 listener    将要被添加的回调函数
18   *异常 IllegalStateException       如果isAlive() 返回false
19   */
20  public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)
21  

使用ViewTreeObserver  监听左边layout 绘图之前调用该方法,所以才可以得到右边layout的宽度,否则在left_layout绘制之后,那么将得不到right_layout的真正宽度,在其他方法中再使用right_layout.getWidth(); 得到的值是0

 

 

 5 实现OnGestureListener接口

	
	@Override
	public boolean onDown(MotionEvent arg0) {
		mScrollX=0;
		isScrolling = false;
		return true;
	}

	@Override
	public boolean onFling(MotionEvent event, MotionEvent arg1, float arg2,
			float arg3) {
		 
		return false;
	}

	@Override
	public void onLongPress(MotionEvent arg0) {
		 
		
	}

	@Override
	public boolean onScroll(MotionEvent event0, MotionEvent event1, float distanceX,
			float distanceY) {
		isScrolling = true;
		RelativeLayout.LayoutParams layoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
		
		mScrollX += distanceX;// distanceX:向左为正,右为负
		
		layoutParams.leftMargin-=mScrollX;
		
		
		System.out.println("*********************************");
		System.out.println(event1.getX() -event0.getX()+"(-------)"+mScrollX+"(-------)"+distanceX);
		
		if(layoutParams.leftMargin <= -MAX_WIDTH){
			
			layoutParams.leftMargin=-MAX_WIDTH;
			isScrolling = false;
		}else if(layoutParams.leftMargin >=0){
			
			layoutParams.leftMargin=0;
			isScrolling = false;
			
		}
		
		left_layout.setLayoutParams(layoutParams);
		 
		return false;
	}

	@Override
	public void onShowPress(MotionEvent arg0) {
	 
		
	}

	
	@Override
	public boolean onSingleTapUp(MotionEvent event) {
		
		System.out.println("执行 onSingleTapUp");
		
		RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) left_layout
				.getLayoutParams();
		// 左移动
		if (layoutParams.leftMargin >= 0) {
			new myAscy().execute(-SPEED);
		} else {
			// 右移动
			new myAscy().execute(SPEED);
		}
		
		return true;
	}
	


这里的onScroll方法做下笔记:

一定要使用一个变量mScrollX来保存叠加distanceX的值,不能直接使用distanceX直接和layoutParams.leftMargin 操作,如果不叠加的话,也可以使用event0.getX() -event1.getX() 来代替mScrollX

 

 

6 实现AsyncTask 类,理解比较简单就不重复描述了

	
	class myAscy extends AsyncTask<Integer, Integer, Void>{

		@Override
		protected Void doInBackground(Integer... params) {
			
			 int times=MAX_WIDTH/Math.abs(params[0]);
			 
			 System.out.println("times:"+times+";max_width:"+MAX_WIDTH);
			 
			 for(int i=0;i<times;i++){
			
				 publishProgress(params[0]);
				 try {
					Thread.sleep(Math.abs(params[0]));
				} catch (InterruptedException e) {
					 
					e.printStackTrace();
				}
			 }
			 
			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			RelativeLayout.LayoutParams LayoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
			LayoutParams.width = SCREEN_WIDTH;
			
			System.out.println("values"+values[0]);
			//向右移动
			if(values[0] > 0){
				
				LayoutParams.leftMargin=Math.min(LayoutParams.leftMargin+values[0], 0);
				
			}else{
				
				LayoutParams.leftMargin=Math.max(LayoutParams.leftMargin+values[0], -MAX_WIDTH);
			
			}
			
			left_layout.setLayoutParams(LayoutParams);
		}
		
		
		
	}


 

 7 实现OnTouchListener接口

	@Override
	public boolean onTouch(View arg0, MotionEvent event) {
		 
	 if(event.getAction() ==MotionEvent.ACTION_UP && isScrolling==true){
		
		 RelativeLayout.LayoutParams layoutParams=(RelativeLayout.LayoutParams) left_layout.getLayoutParams();
		 
		if(layoutParams.leftMargin < -SCREEN_WIDTH/2){
			new myAscy().execute(-SPEED); 
		}else{
			new myAscy().execute(SPEED); 
		}
		
	 }
		
	 return gestureDetector.onTouchEvent(event);
	}
	

这里做下笔记, 当用户执行ACTION_UP事件的时候 一定要 &&上 isScrolling 属性,否则的话菜单可能打不来,或者打开后自动合上,所以isScrolling属性是必须的

 

 

 

 

总结:

(1)缺陷1:ListView 的左右 不起效果,代码还不够精简,准备继续向原博客大神学习,实现ListView 的左右滑动

(2)缺陷2:显示菜单的时候菜单不是从右边滑出来的,而是靠左边布局文件移动慢慢浮现的,所以下次这个缺陷也要修改好

虽然已把李刚的android疯狂讲义大部分看完,也把大部分代码敲了一遍,但是总觉得还不是那么实在,看来还是得继续实战多一点小程序,练多点 奋斗

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(简单滑动菜单)