当前位置: 代码迷 >> Android >> Android自定义组件系列【四】——自定义ViewGroup实现双侧滑动
  详细解决方案

Android自定义组件系列【四】——自定义ViewGroup实现双侧滑动

热度:95   发布时间:2016-04-28 06:03:00.0
Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动

在上一篇文章《Android自定义组件系列【3】——自定义ViewGroup实现侧滑》中实现了仿Facebook和人人网的侧滑效果,这一篇我们将接着上一篇来实现双面滑动的效果。

1、布局示意图:


2、核心代码

	@Override	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {		super.onMeasure(widthMeasureSpec, heightMeasureSpec);		mWidth = MeasureSpec.getSize(widthMeasureSpec);  //获取MyScrollView的宽度		mHeight = MeasureSpec.getSize(heightMeasureSpec); //获取MyScrollView的高度		if(!isLocked){			initX = getScrollX();			isLocked = true;		}	}
在该方法中获取到初始的视图坐标偏移量getScrollX()

	@Override	public boolean onTouchEvent(MotionEvent event) {		float x = event.getX();		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("ACTION_DOWN");			mDownX = x;          //记录按下时的x坐标			break;		case MotionEvent.ACTION_UP:			System.out.println("ACTION_UP");			int dis = (int) (x - mDownX);   //滑动的距离			if(Math.abs(dis) > (mWidth * mMenuWeight / 2)){				if(dis > 0){          //如果>0则是向右滑动					toRightMove();				}else{				  //如果<0则是向左滑动					toLeftMove();				}			}			break;		default:			break;		}				return true;	}
监听函数记录下按下和移动的屏幕坐标,求差计算出移动距离,如果这个距离大于阀值 (mWidth * mMenuWeight / 2)则滑动
	public void toRightMove(){		 System.out.println("maxRight = " + maxRight);		 System.out.println("X = "  + getScrollX());		 if(getScrollX() >= initX){			 int dx = (int)(mWidth * mMenuWeight);			 mScroller.startScroll(getScrollX(), 0, -dx, 0, 500);			 if(mListener != null){				 mListener.onChanged();			 }			 invalidate();		 }	}
如果是向右滑动则,如果当前是初始位置(centerView在中间)则可以向右滑动(getScrollX == initX),或者当前左边View可以看见,则可以向右滑动将centerView移动到中间(getScrollX > initX).同理有向左滑动的方法。
	public void toLeftMove(){		System.out.println("maxLeft = " + maxLeft);		 System.out.println("X = "  + getScrollX());		if(getScrollX() <= initX){			int dx = (int)(mWidth * mMenuWeight);			mScroller.startScroll(getScrollX(), 0, dx, 0, 500);			if(mListener != null){				mListener.onChanged();			}			invalidate();		}	}
3、全部代码

MyScrollView.java

package com.example.testscrollto;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.Scroller;public class MyScrollView extends LinearLayout{		private Context mContext;	private int mWidth;	private int mHeight;		private float mMenuWeight = 3.0f / 5; //菜单界面比例		private View mMenuView;   //菜单界面	private View mPriView;	  //内容界面	private View mRightView;  //右边界面		private int maxLeft;	private int maxRight;	private int initX;		private boolean isLocked = false;		private Scroller mScroller;		private OnMenuChangedListener mListener;		public MyScrollView(Context context, AttributeSet attrs) {		super(context, attrs);		mContext = context;		mScroller = new Scroller(mContext);			}	@Override	protected void onLayout(boolean changed, int l, int t, int r, int b) {		super.onLayout(changed, l, t, r, b);		mMenuView.layout(-(int)(mWidth * mMenuWeight), 0, 0, mHeight);		mPriView.layout(0, 0, mWidth, mHeight);		mRightView.layout(mWidth, 0, mWidth + (int)(mWidth * mMenuWeight), mHeight);	}		@Override	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {		super.onMeasure(widthMeasureSpec, heightMeasureSpec);		mWidth = MeasureSpec.getSize(widthMeasureSpec);  //获取MyScrollView的宽度		mHeight = MeasureSpec.getSize(heightMeasureSpec); //获取MyScrollView的高度		if(!isLocked){			initX = getScrollX();			isLocked = true;		}	}		/**设置右滑的菜单View*/	public void setMenu(View menu){		mMenuView = menu;		addView(mMenuView);	}		/**	 * 设置主界面View	 */	public void setPrimary(View primary){		mPriView = primary;		addView(mPriView);	}		public void setRightView(View rightview){		mRightView = rightview;		addView(mRightView);	}		private float mDownX;		@Override	public boolean onTouchEvent(MotionEvent event) {		float x = event.getX();		switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			System.out.println("ACTION_DOWN");			mDownX = x;          //记录按下时的x坐标			break;		case MotionEvent.ACTION_UP:			System.out.println("ACTION_UP");			int dis = (int) (x - mDownX);   //滑动的距离			if(Math.abs(dis) > (mWidth * mMenuWeight / 2)){				if(dis > 0){          //如果>0则是向右滑动					toRightMove();				}else{				  //如果<0则是向左滑动					toLeftMove();				}			}			break;		default:			break;		}				return true;	}		@Override	public void computeScroll() {		super.computeScroll();		if(mScroller.computeScrollOffset()){			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());			postInvalidate();		}	}			public void toRightMove(){		 System.out.println("maxRight = " + maxRight);		 System.out.println("X = "  + getScrollX());		 if(getScrollX() >= initX){			 int dx = (int)(mWidth * mMenuWeight);			 mScroller.startScroll(getScrollX(), 0, -dx, 0, 500);			 if(mListener != null){				 mListener.onChanged();			 }			 invalidate();		 }	}			public void toLeftMove(){		System.out.println("maxLeft = " + maxLeft);		 System.out.println("X = "  + getScrollX());		if(getScrollX() <= initX){			int dx = (int)(mWidth * mMenuWeight);			mScroller.startScroll(getScrollX(), 0, dx, 0, 500);			if(mListener != null){				mListener.onChanged();			}			invalidate();		}	}		 	public interface OnMenuChangedListener{		 public void onChanged();	}			public void setOnMenuChangedListener(OnMenuChangedListener listener){		mListener = listener;	}}
MainActivity.java
package com.example.testscrollto;import android.app.Activity;import android.os.Bundle;import android.view.View;import com.example.testscrollto.MyScrollView.OnMenuChangedListener;public class MainActivity extends Activity {		private MyScrollView mScrollView;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		mScrollView = (MyScrollView)findViewById(R.id.rightscrollview);		final View menu = getLayoutInflater().inflate(R.layout.rightscrollview_menu, null);		final View primary = getLayoutInflater().inflate(R.layout.rightscrollview_primary, null);		final View rightview = getLayoutInflater().inflate(R.layout.rightscrollview_right_menu, null);		mScrollView.setMenu(menu);		mScrollView.setPrimary(primary);		mScrollView.setRightView(rightview);		mScrollView.setOnMenuChangedListener(new OnMenuChangedListener() {						@Override			public void onChanged() {				System.out.println("窗口切换了一次");			}		});	}}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >        <com.example.testscrollto.MyScrollView        android:id="@+id/rightscrollview"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>
其余三个视图界面无限制,可以自由定义,这里就不贴出来了。

4、运行效果:


源代码下载:http://download.csdn.net/detail/lxq_xsyu/7232701

  相关解决方案