(原创)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);
        }
    }

    

}

本文结束.

原文地址:https://www.cnblogs.com/BlogCommunicator/p/4996094.html