[Android] 监听ScrollView惯性滑动事件

android 专栏收录该内容
10 篇文章 0 订阅

[Android] 监听ScrollView惯性滑动事件

​ ScrollView本身并没有对外提供监听方法,好在内部有一个方法可以监听滑动事件。所以如果我们想要监听ScrollView的滑动事件,只需要做以下几点即可。

  1. 自定义一个ScrollView继承系统的ScrollView

  2. 重写 onScrollChanged 方法

  3. 自定义接口监听onScrollChanged,并将其暴露出去

    代码如下

public class ListeningScrollView extends ScrollView {

    private ScrollListener scrollListener;

    public ListeningScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


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

    public void setScrollViewListener(ScrollListener scrollListener) {
        this.scrollListener = scrollListener;
    }

    /**
     * 滑动监听器
     */
    public interface ScrollListener {
        void onScrollChanged(int x, int y, int oldx, int oldy,int computeVerticalScrollRange);
    }

}

接着问题来了,实验证明刚刚那个方法无法监听到惯性滑动(即只能监听到手指按下时ScrollView的滑动情况),所以我们需要做一下操作,监听手指松开后的惯性滑动事件。

  1. 重写 onTouchEvent 方法。
  2. 当 onTouchEvent 方法捕获到手指松开时,隔一段时间getScrollY(),如果数据和上次不一致就说明正在惯性滑动中。

可以监听惯性滚动事件的代码如下

public class ListeningScrollView extends ScrollView {

    /**
     * 上次的Y坐标
     */
    private int lastY = 0;
    private ScrollYListener scrollYListener;
    private ScrollListener scrollListener;
    private static final int SCROLL_TIME = 20;

    private static final int SCROLL_WHAT = 111;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case SCROLL_WHAT:
                    int scrollY = getScrollY();
                    DebugUtils.printLogE("收到滑动事件" + scrollY);
                    if (lastY != scrollY) {
                        lastY = scrollY;
                        scrollYListener.onScrollChanged(scrollY);
                        handler.sendEmptyMessageDelayed(SCROLL_WHAT, SCROLL_TIME);
                    }
                    break;
            }
        }
    };

    public ListeningScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollYViewListener(ScrollYListener scrollYListener) {
        this.scrollYListener = scrollYListener;
    }

    public void setScrollViewListener(ScrollListener scrollListener) {
        this.scrollListener = scrollListener;
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollYListener != null) {
            scrollYListener.onScrollChanged(t);
        }
        if(scrollListener != null){
            scrollListener.onScrollChanged(l,t,oldl,oldt,computeVerticalScrollRange());
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                if (scrollYListener != null) {
                    handler.sendEmptyMessage(SCROLL_WHAT);
                    DebugUtils.printLogE("发送滑动事件");
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 带惯性的滑动监听器
     */
    public interface ScrollYListener {
        void onScrollChanged(int y);
    }

    /**
     * 滑动监听器
     */
    public interface ScrollListener {
        void onScrollChanged(int x, int y, int oldx, int oldy,int computeVerticalScrollRange);
    }
}

ITDogFire –弓长剑鸣

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值