项目中须要检測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当着研究实习生面训了一次。真心不好受。还是提高自己的能力,有时间自己多学习。有能力了不用去苦心证明自己