zoukankan      html  css  js  c++  java
  • 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
    		
    	}
    	
    
    
    }

    好了。上面两个类的封装非常easy。但却非常完美,每一个事件的逻辑处理分离了。ListView之类的控件仅仅须要把自己的touchlistener事件传递进去就能够了。

    这个能够举一反三运用到其他地方去,以后写代码框架非常重要。事物逻辑要做到分离。这样代码写的非常完美无可挑剔。

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





  • 相关阅读:
    价值理论的出发点和落脚点都是人--以人为本
    价值理论是人类决策和行为的标尺
    事实判断和价值判断
    什么是价值理论?---人们认识世界和改造世界的过程可分解为四个基本阶段
    大人只看利弊 小孩才分对错
    为人处世、事实判断和价值判断皆不可少--人类认识客观事物的标尺:对错与利弊
    知行之间--价值与真理--行动的标尺
    事实判断与价值判断之间的桥梁就是人的需要
    10分钟梳理MySQL核心知识点
    postman设置环境变量,实现一套接口根据选择的环境去请求不同的url
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5285958.html
Copyright © 2011-2022 走看看