ScrollView的滚动监听,得到滚动的距离

在开发中不免会用到ScrollView,用到了ScrollView当然不免想要实时获取到ScrollView滑动的距离,系统的ScrollView并没有给出相对应的监听来得到ScrollView滑动的距离,以下自定义的一个view,继承ScrollView来监听滑动的距离。和普通的ScrollView用法一样,

推荐个薅羊毛交流群,帮助大家日常赚点零花钱 364739778,不要指望这个发财哦
package com.wintegrity.listfate.view;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * 监听scrollView 滑动的距离
 * 
 * @author  2016-11-9 下午1:36:11
 */
public class YScrollView extends ScrollView {
    private static final String TAG = YScrollView.class.getSimpleName();
    // 检查ScrollView的最终状态
    private static final int CHECK_STATE = 0;
    // 外部设置的监听方法
    private OnScrollListener onScrollListener;
    // 是否在触摸状态
    private boolean inTouch = false;
    // 上次滑动的最后位置
    private int lastT = 0;

    /**
     * 构造方法
     * 
     * @param context
     */
    public YScrollView(Context context) {
        super(context);
    }

    /**
     * 构造方法
     * 
     * @param context
     * @param attrs
     */
    public YScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 构造方法
     * 
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public YScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            inTouch = true;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            inTouch = false;
            lastT = getScrollY();
            checkStateHandler.removeMessages(CHECK_STATE);// 确保只在最后一次做这个check
            checkStateHandler.sendEmptyMessageDelayed(CHECK_STATE, 5);// 5毫秒检查一下
            break;
        default:
            break;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (onScrollListener == null) {
            return;
        }

        if (inTouch) {
            if (t != oldt) {
                // 有手指触摸,并且位置有滚动
                onScrollListener.onScrollStateChanged(this,
                        OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            }
        } else {
            if (t != oldt) {
                // 没有手指触摸,并且位置有滚动,就可以简单的认为是在fling
                onScrollListener.onScrollStateChanged(this,
                        OnScrollListener.SCROLL_STATE_FLING);
                // 记住上次滑动的最后位置
                lastT = t;
                checkStateHandler.removeMessages(CHECK_STATE);// 确保只在最后一次做这个check
                checkStateHandler.sendEmptyMessageDelayed(CHECK_STATE, 5);// 5毫秒检查一下
            }
        }
        onScrollListener.onScrollChanged(l, t, oldl, oldt);
    }

    private Handler checkStateHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (lastT == getScrollY()) {
                // 如果上次的位置和当前的位置相同,可认为是在空闲状态
                if (onScrollListener != null) {
                    onScrollListener.onScrollStateChanged(YScrollView.this,
                            OnScrollListener.SCROLL_STATE_IDLE);
                }
                if (getScrollY() + getHeight() >= computeVerticalScrollRange()) {
                    onScrollListener.onBottomArrived();
                } else {
                }
            }
        }
    };

    /**
     * 设置滚动监听事件
     * 
     * @param onScrollListener
     *            {@link OnScrollListener} 滚动监听事件(注意类的不同,虽然名字相同)
     */
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    /**
     * 滚动监听事件
     * 
     * @author aYang
     * 
     */
    public interface OnScrollListener {
        /**
         * The view is not scrolling. Note navigating the list using the
         * trackball counts as being in the idle state since these transitions
         * are not animated.
         */
        public static int SCROLL_STATE_IDLE = 0;

        /**
         * The user is scrolling using touch, and their finger is still on the
         * screen
         */
        public static int SCROLL_STATE_TOUCH_SCROLL = 1;

        /**
         * The user had previously been scrolling using touch and had performed
         * a fling. The animation is now coasting to a stop
         */
        public static int SCROLL_STATE_FLING = 2;

        /**
         * 滑动到底部回调
         */
        public void onBottomArrived();

        /**
         * 滑动状态回调
         * 
         * @param view
         *            当前的scrollView
         * @param scrollState
         *            当前的状态
         */
        public void onScrollStateChanged(YScrollView view, int scrollState);

        /**
         * 滑动位置回调
         * 
         * @param l
         * @param t
         * @param oldl
         * @param oldt
         */
        public void onScrollChanged(int l, int t, int oldl, int oldt);
    }
}

java代码中如下使用

mScrollView.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(YScrollView view, int scrollState) {

    }

    @Override
    public void onScrollChanged(int l, int t, int oldl, int oldt) {
    // 这里的t就是我们想要的距离
    }

    @Override
    public void onBottomArrived() {
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值