zoukankan      html  css  js  c++  java
  • (原创)RecyclerView结合xUtils2.6实现滚动时不加载item,xUtils2.6的源码分析与改造

    我们知道xUtils中的bitmapUtils与listview相配合可以实现滚动时暂停加载

    只需要一句话:

    listview.addOnScrollListener(new PauseOnScrollListener(
                    bitmapUtils, false, true));

    然而在我所使用的xUtils2.6版本上,如果想对recyclerView使用相似的方法是行不通的

    (ps:因为xUtils3只支持api14,所以我没用xUtils3)

    recyclerView.addOnScrollListener(new PauseOnScrollListener(
                    bitmapUtils, false, true));

    因为参数需要的是RecyclerView.OnScrollListener,

    而xUtils只提供了实现AbsListView.OnScrollListener的listener

    这个时候只能自己动手改动xUtils源码了

    进入到PauseOnScrollListener的源码中

    import android.widget.AbsListView;
    import android.widget.AbsListView.OnScrollListener;
    import com.lidroid.xutils.BitmapUtils;
    import com.lidroid.xutils.task.TaskHandler;
    
    public class PauseOnScrollListener implements OnScrollListener {
    
        private TaskHandler taskHandler;
    
        private final boolean pauseOnScroll;
        private final boolean pauseOnFling;
        private final OnScrollListener externalListener;
    
        /**
         * Constructor
         *
         * @param taskHandler   {@linkplain BitmapUtils} instance for controlling
         * @param pauseOnScroll Whether {@linkplain BitmapUtils#pause() pause loading} during touch scrolling
         * @param pauseOnFling  Whether {@linkplain BitmapUtils#pause() pause loading} during fling
         */
        public PauseOnScrollListener(TaskHandler taskHandler, boolean pauseOnScroll, boolean pauseOnFling) {
            this(taskHandler, pauseOnScroll, pauseOnFling, null);
        }
    
        /**
         * Constructor
         *
         * @param taskHandler    {@linkplain BitmapUtils} instance for controlling
         * @param pauseOnScroll  Whether {@linkplain BitmapUtils#pause() pause loading} during touch scrolling
         * @param pauseOnFling   Whether {@linkplain BitmapUtils#pause() pause loading} during fling
         * @param customListener Your custom {@link android.widget.AbsListView.OnScrollListener} for {@linkplain android.widget.AbsListView list view} which also will
         *                       be get scroll events
         */
        public PauseOnScrollListener(TaskHandler taskHandler, boolean pauseOnScroll, boolean pauseOnFling, OnScrollListener customListener) {
            this.taskHandler = taskHandler;
            this.pauseOnScroll = pauseOnScroll;
            this.pauseOnFling = pauseOnFling;
            externalListener = customListener;
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            switch (scrollState) {
                case OnScrollListener.SCROLL_STATE_IDLE:
                    taskHandler.resume();
                    break;
                case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                    if (pauseOnScroll) {
                        taskHandler.pause();
                    }
                    break;
                case OnScrollListener.SCROLL_STATE_FLING:
                    if (pauseOnFling) {
                        taskHandler.pause();
                    }
                    break;
            }
            if (externalListener != null) {
                externalListener.onScrollStateChanged(view, scrollState);
            }
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (externalListener != null) {
                externalListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
            }
        }
    }

    意外地发现不是很长,其中主要起作用的除了两个重写的方法外,就是TaskHandler这个接口了

    BitmapUtils其实是继承了TaskHandler

    TaskHandler对handler进行了进一步的封装,方便控制异步任务

    TaskHandler具有pause()和resume()两个很重要的方法,由BitmapUtils等实现

    @Override
        public void pause() {
            pauseTask = true;
            flushCache();
        }
    
        @Override
        public void resume() {
            pauseTask = false;
            synchronized (pauseTaskLock) {
                pauseTaskLock.notifyAll();
            }
        }

    看到这里思路就比较明显了,我们继承RecyclerView.OnScrollListener并重写其中的回调方法

    在回调方法中调用TaskHandler的api,即可达到想要的效果.

    精简后的代码如下

    import com.lidroid.xutils.BitmapUtils;
    import com.lidroid.xutils.task.TaskHandler;
    
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.RecyclerView.OnScrollListener;
    
    ;
    
    public class PauseOnScrollListener extends RecyclerView.OnScrollListener {
        private TaskHandler taskHandler;
    
        private boolean pauseOnScroll;
        private boolean pauseOnFling;
        private OnScrollListener externalListener;
    
        /**
         * Constructor
         *
         * @param taskHandler
         *            {@linkplain BitmapUtils} instance for controlling
         * @param pauseOnScroll
         *            Whether {@linkplain BitmapUtils#pause() pause loading} during
         *            touch scrolling
         * @param pauseOnFling
         *            Whether {@linkplain BitmapUtils#pause() pause loading} during
         *            fling
         */
        public PauseOnScrollListener(TaskHandler taskHandler,
                boolean pauseOnScroll, boolean pauseOnFling) {
            this(taskHandler, pauseOnScroll, pauseOnFling, null);
        }
    
        /**
         * Constructor
         *
         * @param taskHandler
         *            {@linkplain BitmapUtils} instance for controlling
         * @param pauseOnScroll
         *            Whether {@linkplain BitmapUtils#pause() pause loading} during
         *            touch scrolling
         * @param pauseOnFling
         *            Whether {@linkplain BitmapUtils#pause() pause loading} during
         *            fling
         * @param customListener
         *            Your custom
         *            {@link android.widget.AbsListView.OnScrollListener} for
         *            {@linkplain android.widget.AbsListView list view} which also
         *            will be get scroll events
         */
        public MyPauseOnScrollListener(TaskHandler taskHandler,
                boolean pauseOnScroll, boolean pauseOnFling,
                OnScrollListener customListener) {
            this.taskHandler = taskHandler;
            this.pauseOnScroll = pauseOnScroll;
            this.pauseOnFling = pauseOnFling;
            externalListener = customListener;
        }
    
        @Override
            public void onScrollStateChanged(RecyclerView view, int newState) {
                switch (newState) {
    
                    case 0:
                        taskHandler.resume();
                        break;
    
                    case 1:
                        if (pauseOnScroll) {
                            taskHandler.pause();
                        }
                        break;
    
                    case 2:
                        if (pauseOnFling) {
                            taskHandler.pause();
                        }
                        break;
                }
                if (externalListener != null) {
                    externalListener.onScrollStateChanged(view, scrollState);
                }
            }
    
        
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (externalListener != null) {
                externalListener.onScrolled(recyclerView, dx, dy);
            }
        }
    
        
    
    }

    本文结束.

  • 相关阅读:
    不知道搜索引擎对display:none和visibility:hidden是怎么个看法
    《Effective C#中文版:改善C#程序的50种方法》前言
    SEO实践之网站内部结构设计优化
    友情提示:职场修炼,参加招聘会注意事项
    CSS命名规范
    发布两款纯CSS编写的下拉菜单已测IE6,7,8,FF均可运行
    解读2010年中国九大SEO新星工作室
    南通SEO爱好者之“拿来主义”!
    轻松一刻——幽默
    大学生进行职业选择要有市场意识
  • 原文地址:https://www.cnblogs.com/BlogCommunicator/p/4996094.html
Copyright © 2011-2022 走看看