很多人会问为什么要用 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 大多都因项目需求而加入下拉刷新,上拉加载更多什么的,所以很多人引用了第三方改过的库,那么这个时候我们就可以通过改它的源码来实现我们的要求。
下面贴上代码:
public class XRecyclerView extends RecyclerView {
public XRecyclerView(Context context) {
this(context, null);
}
public XRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public XRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
addOnScrollListener(new ImageAutoLoadScrollListener());
}
//监听滚动来对图片加载进行判断处理
public class ImageAutoLoadScrollListener extends OnScrollListener{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
switch (newState){
case SCROLL_STATE_IDLE: // The RecyclerView is not currently scrolling.
//当屏幕停止滚动,加载图片
try {
if(getContext() != null) Glide.with(getContext()).resumeRequests();
}
catch (Exception e) {
e.printStackTrace();
}
break;
case SCROLL_STATE_DRAGGING: // The RecyclerView is currently being dragged by outside input such as user touch input.
//当屏幕滚动且用户使用的触碰或手指还在屏幕上,停止加载图片
try {
if(getContext() != null) Glide.with(getContext()).pauseRequests();
}
catch (Exception e) {
e.printStackTrace();
}
break;
case SCROLL_STATE_SETTLING: // The RecyclerView is currently animating to a final position while not under outside control.
//由于用户的操作,屏幕产生惯性滑动,停止加载图片
try {
if(getContext() != null) Glide.with(getContext()).pauseRequests();
}
catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}
}
下面讲下 Listview 的:
Listview 的滑动状态跟 Recyclerview 的不太一样,同样有三个:
SCROLL_STATE_IDLE
SCROLL_STATE_FLING
SCROLL_STATE_TOUCH_SCROLL
其中第一个跟 Recyclerview 一样,滑动停止。
第二个照字面理解就是正在滚动。
至于第三个,网上的资料给的解释是手接触 Listview 会触动一次。
那么我们只需对前两个状态进行判断处理就可以了。
下面贴上 OnScrollStateChanged 部分的代码:
@Override
public void onScrollStateChanged(AbsListView view, int newState) {
switch (newState){
case SCROLL_STATE_IDLE:
//滑动停止
try {
if(getContext() != null) Glide.with(getContext()).resumeRequests();
}
catch (Exception e) {
e.printStackTrace();
}
break;
case SCROLL_STATE_FLING:
//正在滚动
try {
if(getContext() != null) Glide.with(getContext()).pauseRequests();
}
catch (Exception e) {
e.printStackTrace();
}
break;
}
}