(原创)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); } } }
本文结束.