自定义ViewGroup (滚动布局)


/**

 *
 * 转载请标明出处:
http://blog.csdn.net/u013598111/article/details/50268287

 *   @author:【JunTao_sun】
 *
 *
*/







<span style="font-size:18px;">package com.example.voersrcoller;

import android.content.Context;
import android.gesture.Gesture;
import android.support.v4.view.GestureDetectorCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.BounceInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.OverScroller;
import android.widget.Scroller;

public class MyViewGroup extends ViewGroup  {

	private static final String TAG = "MyViewGroup";

	private int downx;
	private DisplayMetrics outMetrics;
	private int screenWidth;
	private int screenHeight;
	private int delx;
	private int curPage;
	private int distant;
	private int falgFirst;
	private boolean isNext;
	private boolean isPre;
	private Scroller scroller;
	private boolean mDrag=true;
	private GestureDetector gesture;
	

	public MyViewGroup(Context context) {
		this(context, null);

	}

	public MyViewGroup(Context context, AttributeSet attrs) {
		this(context, attrs, 0);

	}

	public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		scroller = new Scroller(context, new LinearInterpolator());
		WindowManager manager = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		outMetrics = new DisplayMetrics();
		manager.getDefaultDisplay().getMetrics(outMetrics);
		screenWidth = outMetrics.widthPixels;
		screenHeight = outMetrics.heightPixels;
		gesture=new GestureDetector(context, new GestureListener() );
	}
	//手势监听
	class GestureListener extends SimpleOnGestureListener{

		@Override
		public void onLongPress(MotionEvent e) {
			// TODO Auto-generated method stub
			super.onLongPress(e);
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			// TODO Auto-generated method stub
			return super.onScroll(e1, e2, distanceX, distanceY);
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			if(velocityX>0){
				//如果速度为正 说明移动方向向右  不是第0页或者最后一页 就可以快速滚动  
				curPage= curPage == 0 ? 0 : --curPage;
				 nextOrPre();
			}
			if(velocityX<0) {
				curPage = curPage == getChildCount() - 1 ? getChildCount() - 1
						: ++curPage;

				 nextOrPre();
			
			}
			Log.e(TAG, "velocityX"+velocityX);
			return super.onFling(e1, e2, velocityX, velocityY);
		}
		  
		
		
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		View view = getChildAt(0);
		view.measure(MeasureSpec.makeMeasureSpec(screenWidth,
				MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(
						screenHeight, MeasureSpec.AT_MOST));
		View view1 = getChildAt(1);
		view1.measure(
				MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.AT_MOST),
				MeasureSpec.makeMeasureSpec(screenHeight, MeasureSpec.AT_MOST));
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
     //对子View布局
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		//第一个屏幕
		getChildAt(0).layout(0, 0,  getChildAt(0).getMeasuredWidth(), getChildAt(0).getMeasuredHeight());
		//第二个屏幕
		getChildAt(1).layout(screenWidth, 0, screenWidth * 2,
				getChildAt(0).getMeasuredHeight());
	}

	
	  
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		gesture.onTouchEvent(event);
		int laster = (int) event.getX();
      
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			
			
			downx = (int) event.getX();
			
			falgFirst = (int) event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
            //滑动距离
			distant = laster - falgFirst;
			//每滑动  位移实际距离
			delx = laster-downx;
			downx=laster;
			
			//阻尼拖拉  
			//判断是否第一或者最后一页 如果是 执行限制操作 screenWidth/8 并且阻止正常拖拉mDrag=false;
  if(curPage==0&&distant>0||curPage==getChildCount()-1&&distant<=0){
	         //屏蔽不带阻尼的 滚动
			   mDrag=false;
			 if(Math.abs(distant)>=screenWidth/8)delx=screenWidth/5;
			   if(Math.abs(distant)<screenWidth/8){
				   
				   scrollBy(-delx, 0);
				  
				   break;   
			   }
			  
		   }
		   
		   //如果不是第一页和最后一页 就正常拖动
		   if(mDrag){
			   
		   scrollBy(-delx, 0);
		 
		   }
	
			break;

		case MotionEvent.ACTION_UP:
			//判断是否要  滚动前后页
			isPre = isNext = Math.abs(distant) >= screenWidth / 2 ? true
					: false;
			//判断是否下一张滚动
			if (distant < 0 && isNext) {
				//curPage 后一页
				curPage = curPage == getChildCount() - 1 ? getChildCount() - 1
						: ++curPage;

				 nextOrPre();
		   //判断是否要滚动上一页 
			} else if (distant >= 0 && isPre) {
				//curPage 前一页
				curPage= curPage == 0 ? 0 : --curPage;
				 nextOrPre();

			}
			//回滚当前页面  如果不是像前后滚动
			if (!isNext || !isPre) {
				
				nextOrPre();

			}
		  mDrag=true;
			break;

		}

		return true;
	}

	/**
	 * 滚动到当前页数
	 */
	private void nextOrPre() {

	scroller.startScroll(getScrollX(), 0,
				curPage * screenWidth - getScrollX(), 0, 250);
		invalidate();
	}

	//计算滚动距离
	@Override
	public void computeScroll() {
		//scroller.computeScrollOffset() true 说明 没滚动结束
		if (scroller.computeScrollOffset()) {

			scrollTo(scroller.getCurrX(), 0);
			
			invalidate();

		}

		 super.computeScroll();
	}

}
</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值