GestureDetector封裝手勢檢測上下滑動

mx64 9年前發布 | 11K 次閱讀 Android開發 移動開發 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;  
    }  

}  </pre><br />

處理動畫顯示隱藏事件邏輯處理類

    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  

    }  



}  </pre><br />

好了,上面兩個類的封裝很簡單,但卻很完美,每個事件的邏輯處理分離了,ListView之類的控件只需要把自己的touchlistener事件傳遞進去就可以了。這個可以舉一反三運用到其它地方去,以后寫代碼框架很重要,事物邏輯要做到分離,這樣代碼寫的很完美無可挑剔.

來自:http://blog.csdn.net/fancylovejava/article/details/46602669

 本文由用戶 mx64 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!