滚动RecyclerView加载图片时的流畅度优化

时间:2021-11-08 16:47:31

在RecyclerView列表滚动时,如果item中需要网络加载的图片资源过多或过大,会造成掉帧卡顿的问题,用户体验不是很好,尤其是在滚动非常快的情况下。

研究QQ聊天列表时发现,在滑动过程中,用户头像是不会显示的,只使用本地图片资源占位,当惯性滚动停下来时,才进行网络请求加载图片并进行绘制。这样整个过程都不会卡顿。

实现:使用onScrollStateChanged回调检测滚动状态,并在RecyclerViewAdapter内部设置类似isScrolling的状态值来控制网络图片的加载。
下面是代码举例:

// BaseAdapter中添加如下代码
public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
……
protected boolean isScrolling = false;
……
public void setScrolling(boolean scrolling) {
isScrolling = scrolling;
}
}

具体的子Adapter实现:

// 在子Adapter中的onBind里进行控制
public class SubRecyclerViewAdapter extends BaseRecyclerViewAdapter<DataGuardRanking> {
……
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
RecyclerViewHolder holder = (RecyclerViewHolder) viewHolder;
……
if (!TextUtils.isEmpty(data.getAvatarUrl()) && !isScrolling) {
// 这里可以用Glide等网络图片加载库
} else {
holder.avatarImg.setImageResource(占位图本地资源);
}
super.onBindViewHolder(holder, position);
}
}

在UI层进行监听:

// 外部对RecyclerView设置监听
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
// 查看源码可知State有三种状态:SCROLL_STATE_IDLE(静止)、SCROLL_STATE_DRAGGING(上升)、SCROLL_STATE_SETTLING(下落)
if (newState == SCROLL_STATE_IDLE) { // 滚动静止时才加载图片资源,极大提升流畅度
mRecyclerViewAdapter.setScrolling(false);
mRecyclerViewAdapter.notifyDataSetChanged(); // notify调用后onBindViewHolder会响应调用
} else
mRecyclerViewAdapter.setScrolling(true);
super.onScrollStateChanged(recyclerView, newState);
}
});
mRecyclerView.setAdapter(mRecyclerViewAdapter);