實現 ViewPager 回彈效果

實現 ViewPager 回彈效果

在開發過程中,遇到產品需要實現回彈效果,我通過繼承V4中的ViewPager來實現,
具體代碼如下:

mport android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

import cn.wps.moffice.main.scan.util.DeviceInfoUtils;


public class ZoomViewPager extends ScanViewPager {
    private float preX = 0f;
    private static final float RATIO = 0.5f;//摩擦係數

    private int maxOffset;
    private boolean isScrollable = true;
    private boolean isEnableSpringBack = true;
    private int mActivePointerId;
    private int screenWidth;


    public void setEnableSpringBack(boolean isEnableSpringBack) {
        this.isEnableSpringBack = isEnableSpringBack;
    }

    public ZoomViewPager(Context context) {
        super(context);
        init(context);
    }


    public ZoomViewPager(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }


    private void init(Context context) {
        screenWidth = DeviceInfoUtils.getScreenInfo(getContext()).width;
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isScrollable == false) {
            return false;
        }
        if (handleSpringBackEvent(ev)) {
            return true;
        } else {
            try {
                return super.onTouchEvent(ev);
            } catch (Exception e) {
                return false;
            }

        }

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isScrollable == false) {
            return false;
        } else {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                handleActionDown(ev);
            }
            try {
                return super.onInterceptTouchEvent(ev);
            } catch (Exception e) {
                return false;
            }
        }

    }


    private void handleActionDown(MotionEvent ev) {
        mActivePointerId = ev.getPointerId(0);
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        preX = ev.getX(pointerIndex);
        maxOffset =  screenWidth / 2 + getScrollX();
    }

    /**
     * 處理回彈效果
     *
     * @param ev
     * @return
     */
    public boolean handleSpringBackEvent(MotionEvent ev) {
        if (!isEnableSpringBack) return false;
        if (getAdapter() == null) return false;

        int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                handleActionDown(ev);
                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                handleActionUp();
                break;
            case MotionEvent.ACTION_POINTER_UP:
                int index = ev.getActionIndex();
                int id = ev.getPointerId(index);
                if (mActivePointerId == id) {
                    final int newIndex = index == 0 ? 1 : 0;
                    mActivePointerId = ev.getPointerId(newIndex);
                    preX = ev.getX(newIndex);
                }
                break;

            case MotionEvent.ACTION_MOVE:
                float nowX = getActiveX(ev);
                float offset = nowX - preX;
                preX = nowX;

                if (getCurrentItem() == 0 && getAdapter().getCount() > 1) {
                    if (!isCheck) {
                        isCheck = true;
                        if (offset > 0) {
                            isEnableBounce = true;
                        }
                    }

                    if (isEnableBounce) { //處理回彈效果
                        if (Math.abs(getScrollX()) <= maxOffset || offset < 0) {
                            scrollBy((int) -(offset * RATIO), 0);
                            invalidate();
                        }
                        return true;
                    }
                }

                if (getCurrentItem() == getAdapter().getCount() - 1 && getAdapter().getCount() > 1) {
                    if (!isCheck) { //
                        isCheck = true;
                        if (offset < 0) {
                            isEnableBounce = true;
                        }
                    }

                    if (isEnableBounce) { //處理回彈效果
                        if (Math.abs(getScrollX()) <= maxOffset || offset > 0) {
                            scrollBy((int) -(offset * RATIO), 0);
                            invalidate();
                        }
                        return true;
                    }

                }

                break;
        }
        return false;
    }


    private float getActiveX(MotionEvent ev) {
        try {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            return ev.getX(pointerIndex);
        } catch (Exception e) {
            return ev.getX();
        }
    }


    private boolean isEnableBounce = false;
    private boolean isCheck = false;

    private void handleActionUp() {
        if (isCheck && isEnableBounce) {
            setIsBeingDragged(true);
        }
        isCheck = false;
        isEnableBounce = false;
    }

    public boolean isScrollable() {
        return isScrollable;
    }

    public void setScrollable(boolean isScrollable) {
        this.isScrollable = isScrollable;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章