Glide结合Recyclerview(也适用于Listview)实现列表滑动的时候图片不加载,滑动停止的时候加载(已修正Listview部分以及排版)

来源:互联网 发布:防蹭网软件苹果版 编辑:程序博客网 时间:2024/05/18 13:04

写在前面,其实Glide配合RecyclerView使用时是会优先加载可见的item的,当然你也可以使用priority来控制优先级


很多人会问为什么要用 glide,其它的库可以么?其实只要图片库带有对应的方法都是可以的,只不过真心觉得这个库不错,就算是推荐吧。

然后着重讲 Recyclerview 是因为 Recyclerview 在 adapter 的onBindViewHolder 中对item的操作比较严格,如果处理操作比较多,耗时长(比如单个item的图片比较多)就会造成Recyclerview卡的现象(Listview 就没有这么严格),所以针对 Recyclerview 我们得进行特殊优化。


调出 glide 的方法,发现有两个方法:

Glide.with(context).resumeRequests();
Glide.with(context).pauseRequests();

根据方法名称不难理解:

其中第一个是恢复图片的请求加载,第二个是暂停图片的请求加载。

接下来我们就要看 Recyclerview(Listview同样)了,其中有一个 OnScrollListener ,这个就是对列表滑动的监听。

那么我们只要在滑动中和滑动停止这两种状态下对图片加载进行对应处理就可以了。


然后我们来看看 OnScrollListener 里面的两个方法:

onScrolled(RecyclerView recyclerView, int dx, int dy)
onScrollStateChanged(RecyclerView recyclerView, int newState)

其中我们需要关注第二个方法。第二个参数 newState 就是滑动的状态,有三个:

SCROLL_STATE_IDLE
SCROLL_STATE_DRAGGING
SCROLL_STATE_SETTLING

第一个英文解释是这样的:

The RecyclerView is not currently scrolling.

顾名思义,就是停止滑动。

第二个:

The RecyclerView is currently being dragged by outside input such as user touch input.

可以理解为:当屏幕滚动且用户使用的触碰或手指还在屏幕上。

第三个:

The RecyclerView is currently animating to a final position while not under outside control.

可以理解为:由于用户的操作,屏幕产生惯性滑动。


那么接下来我们只需要进行判断然后再调用 Glide 对应的方法就可以了,其中第一个状态要恢复图片请求加载,剩下的两个状态就要暂停图片请求加载。

最后提醒一下,因为 Recyclerview 大多都因项目需求而加入下拉刷新,上拉加载更多什么的,所以很多人引用了第三方改过的库,那么这个时候我们就可以通过改它的源码来实现我们的要求。


下面贴上代码:

[java] view plain copy
  1. public class XRecyclerView extends RecyclerView {  
  2.     public XRecyclerView(Context context) {  
  3.         this(context, null);  
  4.     }  
  5.   
  6.     public XRecyclerView(Context context, AttributeSet attrs) {  
  7.         this(context, attrs, 0);  
  8.     }  
  9.   
  10.     public XRecyclerView(Context context, AttributeSet attrs, int defStyle) {  
  11.         super(context, attrs, defStyle);  
  12.         init();  
  13.     }  
  14.   
  15.     private void init() {  
  16.         addOnScrollListener(new ImageAutoLoadScrollListener());  
  17.     }  
  18.   
  19.     //监听滚动来对图片加载进行判断处理  
  20.     public class ImageAutoLoadScrollListener extends OnScrollListener{  
  21.   
  22.         @Override  
  23.         public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
  24.             super.onScrolled(recyclerView, dx, dy);  
  25.         }  
  26.   
  27.         @Override  
  28.         public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
  29.             super.onScrollStateChanged(recyclerView, newState);  
  30.             switch (newState){  
  31.                 case SCROLL_STATE_IDLE: // The RecyclerView is not currently scrolling.  
  32.                     //当屏幕停止滚动,加载图片  
  33.                     try {  
  34.                         if(getContext() != null) Glide.with(getContext()).resumeRequests();  
  35.                     }  
  36.                     catch (Exception e) {  
  37.                         e.printStackTrace();  
  38.                     }  
  39.                     break;  
  40.                 case SCROLL_STATE_DRAGGING: // The RecyclerView is currently being dragged by outside input such as user touch input.  
  41.                     //当屏幕滚动且用户使用的触碰或手指还在屏幕上,停止加载图片  
  42.                     try {  
  43.                         if(getContext() != null) Glide.with(getContext()).pauseRequests();  
  44.                     }  
  45.                     catch (Exception e) {  
  46.                         e.printStackTrace();  
  47.                     }  
  48.                     break;  
  49.                 case SCROLL_STATE_SETTLING: // The RecyclerView is currently animating to a final position while not under outside control.  
  50.                     //由于用户的操作,屏幕产生惯性滑动,停止加载图片  
  51.                     try {  
  52.                         if(getContext() != null) Glide.with(getContext()).pauseRequests();  
  53.                     }  
  54.                     catch (Exception e) {  
  55.                         e.printStackTrace();  
  56.                     }  
  57.                     break;  
  58.             }  
  59.         }  
  60.     }  
  61. }  

有人会问为什么要加上 try catch 呢,其实主要是为了避免一些情况下导致的崩溃(比如 context 已经销毁但不为 null 的情况),算是加上一层保险吧。


下面讲下 Listview 的:

Listview 的滑动状态跟 Recyclerview 的不太一样,同样有三个:

SCROLL_STATE_IDLE

SCROLL_STATE_FLING

SCROLL_STATE_TOUCH_SCROLL


其中第一个跟 Recyclerview 一样,滑动停止。

第二个照字面理解就是正在滚动。

至于第三个,网上的资料给的解释是手接触 Listview 会触动一次。


那么我们只需对前两个状态进行判断处理就可以了。

下面贴上 OnScrollStateChanged 部分的代码:

[java] view plain copy
  1. @Override  
  2.     public void onScrollStateChanged(AbsListView view, int newState) {  
  3.   
  4.         switch (newState){  
  5.             case SCROLL_STATE_IDLE:  
  6.                 //滑动停止  
  7.                 try {  
  8.                     if(getContext() != null) Glide.with(getContext()).resumeRequests();  
  9.                 }  
  10.                 catch (Exception e) {  
  11.                     e.printStackTrace();  
  12.                 }  
  13.                 break;  
  14.             case SCROLL_STATE_FLING:  
  15.                 //正在滚动  
  16.                 try {  
  17.                     if(getContext() != null) Glide.with(getContext()).pauseRequests();  
  18.                 }  
  19.                 catch (Exception e) {  
  20.                     e.printStackTrace();  
  21.                 }  
  22.                 break;  
  23.   
  24.         }  
  25.   
  26.     }  


    阅读全文
    0 0