对Recyclerview上下左右等动作监听优化的封装(重点在优化哟)

本文介绍了一种优化的RecyclerView滑动监听方法,通过锁机制确保滑动方向改变时仅触发一次事件,避免了重复回调的问题,并提供了易于扩展的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   Hellow小伙伴们,好久没更新了,最近忙死了,最近在做项目的时候要用到Recyclerview,并且要监听它的滑动,这时就上网查了一下,我滴乖乖,好老的博客,不过能用,但是在学他们使用的时候发现了一个致命的问题,你只要动一下就能监测到你的变化。或许这里表述不清楚,那么我们直接看具体案列。


这里可能需要花费你很多时间阅读,但是弄清楚了对你是个巨大的飞跃并且,我只做了对上下滑动的监听,弄懂如下代码之后就可以实现对左右左上,左下等方向的监听了.



  实现方法一(最原始的):

     ReyclerView中有个ScrollListener这个监听

 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if(newState == 0)
                {
                    //表示屏幕已停止。屏幕停止滚动时为
                }else  if(newState == 1){
                   //表示正在滚动。当屏幕滚动且用户使用的触碰或手指还在屏幕上时为
                }else  if(newState == 2){
                    //表示手指做了抛的动作(手指离开屏幕前,用力滑了一下,屏幕产生惯性滑动)。
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if(dy>0){
                    //向上滑动
                }
                else{
                    //向下滑动
                }
                    
            }
        });


    这个是可以实现我们的上下左右滑动的监听的,但是致命问题也就在这,当你一直往下或者上滑动的时候,这个方法将一直被触发。问题就在这,可能你要在当recyclerView向下滑动的额时候你要做某些操作,这时候你持续往下滑这个方法将会倍执行N次,这不是我们想要的。

    所以这个时候,我们想要的是向下滑动的时候就触发一次,向上滑动的时候就触发一次。这个该怎么来实现嫩。学过数据库的人应该很容易联想到我们的锁的概念,当执行某个事物的时候其他事件不能去抢占执行他。

  所以我们有了一个大体的思路。

      1.当手指向上滑动的时候,触发一次向上滑动,锁定它,不再触发。即使手指还在向上滑动

      2.当手指向下滑动的时候,触发一次向下滑动,锁定它,不再触发。即使手指还在向下滑动

      3.当手指滑动方向发生改变的时候,释放我们的锁.

这么一来不就可以实现了么?

下面是我封装的一个可以拓展的RecyclerViewHelper,简单的实现了想要实现的逻辑,拓展非常容易(囊括了接口回调,不动的我的博客有详解,以及我们的Builder设计模式,还有实现多接口实现其中的某个方法)


  


/**
 * Created by meng on 2018/2/9.
 */

public  class RecyclerHelper extends RecyclerView.OnScrollListener {

    private mScrollListener mListener;

    private RecyclerView recyclerView;

    private boolean LOCK_Y;//锁住Y方向的滑动
    private boolean LOCK_X;//锁住X方向的滑动


    private float OLD_DY = -1;//临时存放dy
    private float OLD_DX = -1;//临时存放dx



    /**
     * 采用Builder模式来构建
     */
    private RecyclerHelper(){
    }

    private RecyclerHelper(RecyclerHelper recyclerHelper){
        this.recyclerView=recyclerHelper.recyclerView;
    }

    public void setLostener(mScrollListener lostener){
        this.mListener = lostener;
    }


    public void Listener(){
       recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
           @Override
           public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
               super.onScrollStateChanged(recyclerView, newState);
               if(mListener!=null){
                   if(newState == 0)
                       mListener.SCROLL_STATE_IDLE();//表示屏幕已停止。屏幕停止滚动时为
                   else if(newState == 1)
                       mListener.SCROLL_STATE_TOUCH_SCROLL();//表示正在滚动。当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1
                   else if(newState == 2)
                       mListener.SCROLL_STATE_FLING();//表示手指做了抛的动作(手指离开屏幕前,用力滑了一下,屏幕产生惯性滑动)。
               }
           }

           @Override
           public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
               super.onScrolled(recyclerView, dx, dy);
               if(mListener !=null){

                   if((OLD_DY <0&&dy>0) ||(OLD_DY>0&&dy<0))
                   {
                       LOCK_Y = false;//当运动方向发生改变的时候解除对Y轴的锁定
                   }

                   if(dy > 0)
                   {
                        if(!LOCK_Y)
                        {
                            LOCK_Y = true;//手指向上滑动并且要锁住Y轴,防止多彩回调
                            mListener.upGlide();

                        }
                   }

                   else if(dy < 0 )
                   {
                       if(!LOCK_Y)
                       {
                           LOCK_Y = true;//同上
                           mListener.downGlide();

                       }
                   }
                   OLD_DY = dy;//记录旧的DY
               }//end if
           }//end
       });//end onScrolled
    }




    public static class Builder{
        private RecyclerHelper target;

        public Builder(){
            target = new RecyclerHelper();
        }

        public Builder addRecyclerView(RecyclerView recyclerView){
            target.recyclerView = recyclerView;
            return this;
        }

        public Builder addSetScroListener(mScrollListener listener){
            target.mListener = listener;
            return  this;
        }

        public RecyclerHelper build() {
            return new RecyclerHelper(target);
        }
    }





    public interface mScrollListener{
        void upGlide();//手指向上滑动,并且脱离手机
        void downGlide();//手指向下滑动,并且脱离了手机
        void leftGlide();//手指向左滑动
        void rightGlide();//手指向右滑动
        void upAndrightGlide();//手指右上滑动
        void upAndleftGlide();//手指向左上滑动
        void downAndrightGlide();//手指向右下滑动
        void downAndleftGlide();//手指向左下滑动
        void SCROLL_STATE_FLING();//屏幕处于甩动状态
        void SCROLL_STATE_IDLE();//停止滑动状态
        void SCROLL_STATE_TOUCH_SCROLL();// 手指接触状态
    }

    public static  class mScrollListenerImpl implements mScrollListener {
        @Override
        public void upGlide() {

        }

        @Override
        public void downGlide() {

        }

        @Override
        public void leftGlide() {

        }

        @Override
        public void rightGlide() {

        }

        @Override
        public void upAndrightGlide() {

        }

        @Override
        public void upAndleftGlide() {

        }

        @Override
        public void downAndrightGlide() {

        }

        @Override
        public void downAndleftGlide() {

        }

        @Override
        public void SCROLL_STATE_FLING() {

        }

        @Override
        public void SCROLL_STATE_IDLE() {

        }

        @Override
        public void SCROLL_STATE_TOUCH_SCROLL() {

        }
    }
}


   使用方法1:

        

  RecyclerHelper recyclerHelper = new RecyclerHelper.Builder()
                .addRecyclerView(recyclerView)
                .build();
        recyclerHelper.setLostener(new RecyclerHelper.mScrollListenerImpl(){
            @Override
            public void upGlide() {
                super.upGlide();
            }

            @Override
            public void downGlide() {
                super.downGlide();
            }
        });

  使用我们做项目的时候经常用到的Bulider模式,支持相当容易的扩展.

  这里还有一处特别重要的地方为社么这么我们new 的是 mScrollListenerImpl(),而不是mScrollListener(),这就是一个技巧性地问题了,我们平时写一些代码的时候经常会碰到,回调接口过多,但是只想实现其中的一些方法,这个情况下用上述的技巧可以减轻代码量,看着个舒服了.

   使用方法2:直接implements我们的接口就好了.


   支持原创,转载的时候注明转载出处,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值