zoukankan      html  css  js  c++  java
  • RecyclerView滚动事件分析与OnScrollListener的使用

    作为一个目前在Android开发中可能是应用最为广泛之一的组件,RecyclerView在诞生之初就广受好评。而随着对其研究的深入,我们会对它有很多使用需求,一个能滚动的组件,需要监控其滚动事件是非常正常的事情。

    一、列表的滚动事件:

    一个列表在滚动的时候,一般会有两种滚动形式:

    • 手指按下后,不离开屏幕,一直拖动着列表进行滚动,滚动到合适的位置后停下来,手指离开屏幕。
    • 手指按下,在很短时间内用较快的速度拖动列表,然后手指马上离开列表,列表随着惯性,继续滚动到一个位置(或者滚动到尾部)。

    二、如何监听RecyclerView的滚动事件

    稍有经验的开发者,都不难猜到会有一个Listener,在Android Studio里面直接用一个RecyclerView对象进行set或者add的时候,IDE就会提示相应的Listener。是的,Google给我们提供了一个RecyclerView下的OnScrollListener,你可以用addOnScrollListener或setOnScrollListener(已经deprecated了,不建议使用)的方式来监听,下面我们来看看它的源码:

     /**
         * An OnScrollListener can be added to a RecyclerView to receive messages when a scrolling event
         * has occurred on that RecyclerView.
         * <p>
         * @see RecyclerView#addOnScrollListener(OnScrollListener)
         * @see RecyclerView#clearOnChildAttachStateChangeListeners()
         *
         */
        public abstract static class OnScrollListener {
        /**
         * Callback method to be invoked when RecyclerView's scroll state changes.
         *
         * @param recyclerView The RecyclerView whose scroll state has changed.
         * @param newState     The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
         *                     {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
         */
        public void onScrollStateChanged(RecyclerView recyclerView, int newState){}
     
        /**
         * Callback method to be invoked when the RecyclerView has been scrolled. This will be
         * called after the scroll has completed.
         * <p>
         * This callback will also be called if visible item range changes after a layout
         * calculation. In that case, dx and dy will be 0.
         *
         * @param recyclerView The RecyclerView which scrolled.
         * @param dx The amount of horizontal scroll.
         * @param dy The amount of vertical scroll.
        */
        public void onScrolled(RecyclerView recyclerView, int dx, int dy){}
        }
    

    OnScrollListener提供了2个回掉方法,但由于OnScrollListener不是接口而是抽象类,所以你并不是必须同时实现这2个方法,可以根据实际需求来进行实现。下面来看一下这2个方法都有什么作用。
    onScrollStateChanged(RecyclerView recyclerView, int newState)
    很容易看出来,这个方法记录了RecyclerView的滚动状态的变化,2个变量中,第一个自然是当前的RecyclerView组件,第二个则表达了当前滚动状态,它有3个值:

     /**
         * The RecyclerView is not currently scrolling.
         * @see #getScrollState()
         */
        public static final int SCROLL_STATE_IDLE = 0;
    
        /**
         * The RecyclerView is currently being dragged by outside input such as user touch input.
         * @see #getScrollState()
         */
        public static final int SCROLL_STATE_DRAGGING = 1;
    
        /**
         * The RecyclerView is currently animating to a final position while not under
         * outside control.
         * @see #getScrollState()
         */
        public static final int SCROLL_STATE_SETTLING = 2
    

    我特别欣慰,这次Google自己写的注释很详细了。当然如果你英语水平不高我可以给你翻译一下:

    • SCROLL_STATE_IDLE代表RecyclerView现在不是滚动状态。

    • SCROLL_STATE_DRAGGING代表RecyclerView处于被外力引导的滚动状态,比如手指正在拖着进行滚动。

    • SCROLL_STATE_SETTLING代表RecyclerView处于自动滚动的状态,此时手指已经离开屏幕,RecyclerView的滚动是自身的惯性在维持。
      onScrolled(RecyclerView recyclerView, int dx, int dy)
      此方法用来获取RecyclerView的滚动距离,dx和dy自然分别代表横向和纵向的滚动距离啦,这2个值都是可正可负的:

    • 当dx > 0 时,代表手指向左拖动,RecyclerView则从右向左滚动。

    • 当dx < 0时,代表手指向右拖动,RecyclerView则从左向右滚动。

    • 当dy > 0时,代表手指向上拖动,RecyclerView则从上向下滚动(就是我们最常见的,从顶部开始往下滚动)。

    • 当dy < 0时,代表手指向下拖动,RecyclerView则从下向上滚动(就是从列表底部往回挥动)。
      这里再介绍2个很有用的方法:

    • public boolean canScrollVertically(int direction)

    • public boolean canScrollHorizontally(int direction)
      这2个方法实际上并不是RecyclerView所特有的,而是View这个超级类的。这2个方法,可以判断当前View能否在横向或纵向上滚动。当返回false的时候,说明组件已经不能在给定的方向上进行滚动了,而这2个方法,也可以引出一个很常见的问题及解决办法。

    三、如何判断RecyclerView是否滚动到底部或顶部?

    以更常见的纵向来说,使用Recyclerview. canScrollVertically(1),当返回值是false的时候,代表你的RecyclerView不能继续往下滚动啦,也就是说已经滚动到底部了。同理,当Recyclerview. canScrollVertically(-1)返回false的时候代表RecyclerView不能继续网上滚动了,已经到顶部了。这个方法比通过计算当前item的位置以及总item数量的方法进行判断要好多了。

    本文转自:https://www.kaelli.com/14.html

  • 相关阅读:
    Echarts 源码解读 一:zrender源码分析1var zr = zrender.init(document.getElementById(‘main‘));
    Vue3 script setup 语法糖详解
    TCP的状态 (SYN, FIN, ACK, PSH, RST, URG)
    vuerouter路由懒加载
    ECharts 源码解读 二
    前端必备10种设计模式
    VUE路由懒加载的3种方式
    RewriterConfig 配置
    JQ弹出层插件(tipsWindow 2.8)
    一个jQuery弹出层(tipsWindown)
  • 原文地址:https://www.cnblogs.com/sishuiliuyun/p/14447616.html
Copyright © 2011-2022 走看看