GestureDetector封装手势检测上下滑动

项目中需要检测ListView的上滑下滑隐藏顶部View控件,之前在网上也有很多实现案例。在git上发现个封装很不错的例子,记录下来。


GestureDetector是一个手势检测类,内部有个SimpleOnGestureListener手势监听类。

定义一个抽象类SimpleDetector,继承GestureDetector.SimpleOnGestureListener抽象类,实现View.OnTouchListener接口。这样做有什么好处呢?首先ListView只要setOnTouchListener,把定义的这个抽象类SimpleDetector设置进就好。然后这个类SimpleDetector只需要负责检测上滑还是下滑事件,逻辑得到了分离。

为了要实现ListView顶部View控件的动画效果,需要定义另外一个类继承上面抽象的SimpleDetector类,在这个类里单独处理上滑下滑时候需要执行的动画或者其它逻辑事件。上面的SimpleDetector抽象类提供两个抽象方法供子类去实现。这样整个封装就显得非常完美了。

public abstract class SimpleDetector extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener{

	private final GestureDetector mDetector;
	private final int mSlop;//slop晃荡的意思
	private boolean mIgnore;//是否忽略监听上下滚动
	private float mDownY;
	
	public abstract void onScrollDown();
	public abstract void onScrollUp();
	
	public SimpleDetector(Context context){
		mDetector = new GestureDetector(context,this);
		mSlop = getSlop(context);
	}
	
	public boolean isIgnore() {
		return mIgnore;
	}
	public void setIgnore(boolean mIgnore) {
		this.mIgnore = mIgnore;
	}
	protected int getSlop(Context context){
		if(Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){
			return ViewConfiguration.getTouchSlop() * 2;
		}else{
			return ViewConfiguration.get(context).getScaledPagingTouchSlop();
		}
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		mDownY = e.getY();
		return false;
	}
	
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		if(mIgnore)
			return false;
		if(distanceY==0){
			mDownY = e2.getY();
		}
		
		float distance = mDownY - e2.getY();
		
		if(distance < -mSlop){
			onScrollDown();
		}else if(distance > mSlop){
			onScrollUp();
		}
		return false;
	}
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		mDetector.onTouchEvent(event);
		return false;
	}

}

处理动画显示隐藏事件逻辑处理类

public class ShowHideOnScroll extends SimpleDetector implements AnimatorListener{

	private final View mView;
	private int mShowAnimation;
	private int mHideAnimation;
	private int mTranslationY;
	private int curShowHide = 0;
	
	public ShowHideOnScroll(View view,int translationY){
		super(view.getContext());
		mView = view;
		mTranslationY = translationY;
	}
	
	public ShowHideOnScroll(View view,int show,int hide,int translationY) {
		super(view.getContext());
		mView = view;
		mShowAnimation = show;
		mHideAnimation = hide;
		mTranslationY = translationY;
	}

	@Override
	public void onScrollDown() {
		mView.setVisibility(View.VISIBLE);
		animateShow();
		curShowHide = 0;
	}

	@Override
	public void onScrollUp() {
		mView.setVisibility(View.VISIBLE);
		animateHide();
		curShowHide = 1;
	}
	private void animateShow(){
		mView.setTranslationY(mTranslationY);
		mView.animate().translationY(0).setInterpolator(new AccelerateDecelerateInterpolator())
		.setStartDelay(0).setDuration(400).setListener(ShowHideOnScroll.this).start();
		setIgnore(true);
	}
	private void animateHide(){
		mView.setTranslationY(0);
		mView.animate().translationY(mTranslationY).setInterpolator(new AccelerateDecelerateInterpolator())
		.setStartDelay(0).setDuration(400).setListener(ShowHideOnScroll.this).start();
		setIgnore(true);
	}

	@Override
	public void onAnimationStart(Animator animation) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onAnimationEnd(Animator animation) {
		// TODO Auto-generated method stub
		if(curShowHide==0){
			mView.setVisibility(View.VISIBLE);
			mView.setTranslationY(0);
		}else if(curShowHide == 1){
			mView.setVisibility(View.INVISIBLE);
			mView.setTranslationY(mTranslationY);
		}
		setIgnore(false);
	}

	@Override
	public void onAnimationCancel(Animator animation) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onAnimationRepeat(Animator animation) {
		// TODO Auto-generated method stub
		
	}
	


}

好了,上面两个类的封装很简单,但却很完美,每个事件的逻辑处理分离了,ListView之类的控件只需要把自己的touchlistener事件传递进去就可以了。这个可以举一反三运用到其它地方去,以后写代码框架很重要,事物逻辑要做到分离,这样代码写的很完美无可挑剔。

在新公司上了一个多月班了,压力山大,全是高材生,研究生也来写代码,真心的~然后又被boss当着研究实习生面训了一次,真心不好受。还是提高自己的能力,有时间自己多学习,有能力了不用去苦心证明自己





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值