Android 弹性的Viewpager

本文介绍了如何使用TouchMoveHelper类处理Android ViewPager的触摸事件,以及BounceBackViewPager的特殊滚动效果,通过摩擦系数和边界判断提供更流畅的滑动体验。
摘要由CSDN通过智能技术生成

Android 弹性的Viewpager

TouchMoveHelper.java

import android.content.Context;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

public class TouchMoveHelper {

    private PointF positionTemp;
    private TouchEventAdapter touchEventAdapter;
    //判断是否滑动的临界点
    private float touchSlop;

    public TouchMoveHelper(Context context) {
        positionTemp = new PointF();
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        touchEventAdapter = new TouchEventAdapter() {
            @Override
            void onTouchDown() {

            }

            @Override
            void onTouchUp() {

            }

            @Override
            boolean onTouchMove(float offsetX, float offsetY) {
                return false;
            }
        };
    }

    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            touchEventAdapter.onTouchDown();
            recordPosition(ev);
        }
        return touchEventAdapter.onInterceptTouchEvent();
    }

    public boolean onTouchEvent(MotionEvent ev) {
        boolean isDealTouch = false;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                touchEventAdapter.onTouchUp();
                break;
            case MotionEvent.ACTION_MOVE:
                isDealTouch = touchEventAdapter.onTouchMove(getOffset(ev.getRawX() - positionTemp.x), getOffset(ev.getRawY() - positionTemp.y));
                recordPosition(ev);
                break;
        }
        return isDealTouch;
    }

    public abstract static class TouchEventAdapter {
        abstract void onTouchDown();

        abstract void onTouchUp();

        abstract boolean onTouchMove(float offsetX, float offsetY);

        //因为没有拦截子view事件,只是额外处理viewpager的自身事件,所以默认为false,
        boolean onInterceptTouchEvent() {
            return false;
        }
    }

    public void setTouchEventAdapter(TouchEventAdapter touchEventAdapter) {
        this.touchEventAdapter = touchEventAdapter;
    }

    private float getOffset(float offset) {
        if (Math.abs(offset) > touchSlop) {
            return offset;
        } else {
            return 0;
        }
    }

    private void recordPosition(MotionEvent ev) {
        positionTemp.x = ev.getRawX();
        positionTemp.y = ev.getRawY();
    }
}

BounceBackViewPager.java

import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.TranslateAnimation;

public class BounceBackViewPager extends ViewPager {
    private int currentPosition = 0;
    private Rect startRect = new Rect();//用来记录初始位置
    private static final float RATIO = 0.5f;//摩擦系数
    public BounceBackViewPager(Context context) {
        super(context);
    }

    public BounceBackViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    private TouchMoveHelper eventHelper;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        eventHelper = new TouchMoveHelper(getContext());
        eventHelper.setTouchEventAdapter(new TouchMoveHelper.TouchEventAdapter() {
            @Override
            public void onTouchDown() {
                startRect.set(getLeft(), getTop(), getRight(), getBottom());
                currentPosition = getCurrentItem();
            }
            @Override
            public void onTouchUp() {
                recoveryPosition();
            }

            @Override
            boolean onTouchMove(float offsetX, float offsetY) {
                if (isStartPosition() && offsetX > 0||isEndPosition() && offsetX < 0) {
                    moveByTouchOffset(offsetX,0);
                    return true;
                }
                //如果想拦截竖直方向页可以换下参数即可
//                if (isStartPosition() && offsetY > 0||isEndPosition() && offsetY < 0) {
//                    moveByTouchOffset(0,offsetY);
//                    return true;
//                }
                return false;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return eventHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return eventHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
    }

    private boolean isStartPosition() {
        return getAdapter().getCount() == 1 || (getAdapter().getCount() != 1 && currentPosition == 0);
    }

    private boolean isEndPosition() {
        return getAdapter().getCount() == 1 || (getAdapter().getCount() != 1 && currentPosition == getAdapter().getCount() - 1);
    }

    private void moveByTouchOffset(float offsetX,float offsetY) {
        layout(getLeft()+(int)(offsetX * RATIO), getTop() + (int)(offsetY * RATIO), getRight()+(int)(offsetX * RATIO), getBottom() + (int)(offsetY * RATIO));
    }

    private void recoveryPosition() {
        TranslateAnimation ta = new TranslateAnimation(getLeft(), startRect.left, getTop(), startRect.top);
        ta.setDuration(300);
        startAnimation(ta);
        layout(startRect.left, startRect.top, startRect.right, startRect.bottom);
        startRect.setEmpty();
    }
}

其实就是网上找的代码,为了好理解重构了下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值