官方解釋以下:A flexible view for providing a limited window into a large data set. 意思就是說在一個有限的窗口中顯示大量的數據集.緩存
回顧一下之前咱們使用的ListView ListView的侷限性能優化
使用RecyclerView的優點bash
默認支持Linear, Grid, Staggered Grid三種佈局架構
友好的ItemAnimator動畫APIapp
強制實現ViewHolderide
解耦架構設計佈局
相比 ListView更好的性能 RecyclerView支持的佈局性能
ListView中getView暴露的問題fetch
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_view_item, parent, false);
}
/**
* 下面的代碼不管在convertView是否爲null都會執行
*/
ImageView avatar = convertView.findViewById(R.id.user_avatar);
TextView name = convertView.findViewById(R.id.user_name);
TextView title = convertView.findViewById(R.id.user_title);
User user = getItem(position);
Glide.with(parent.getContext()).load(user.avatar).into(avatar);
name.setText(user.name);
title.setText(user.title);
return convertView;
}
複製代碼
上面的代碼在執行getView,每次都會去findViewById,若是view個數比較多findViewById次數就會增多,這樣顯然會下降效率. ViewHolder的出現就是爲了保存View引用的容器類,減小重複findViewById次數,下面來看看用ViewHolder如何優化上面的代碼.flex
public View getView(int position, View convertView, ViewGroup parent) {
UserViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_view_item, parent, false);
holder = new UserViewHolder(convertView);
holder.avater = convertView.findViewById(R.id.user_avatar);
holder.name = convertView.findViewById(R.id.user_name);
holder.title = convertView.findViewById(R.id.user_title);
convertView.setTag(holder);
} else {
holder = (UserViewHolder)convertView.getTag();
}
/**
* 下面的代碼不管在convertView是否爲null都會執行
*/
ImageView avatar = convertView.findViewById(R.id.user_avatar);
TextView name = convertView.findViewById(R.id.user_name);
TextView title = convertView.findViewById(R.id.user_title);
User user = getItem(position);
holder.title.setText(user.title);
holder.name.setText(user.name);
Glide.with(parent.getContext()).load(user.avatar).into(holder.avater);
return convertView;
}
複製代碼
ViewHolder和View的對應關係
在講解RecyclerView緩存機制以前先來看看ListView的緩存機制,它的緩存機制比RecyclerView簡單,可是大致思想是同樣的.
對應到屏幕上
RecyclerView的緩存機制
Scrap: 在屏幕內可視的Item。 Cache: 在屏幕外的Item ViewCacheExtension : 用戶自定義的緩存策略 RecycledViewPool : 被廢棄的itemview,髒數據,須要從新onBindViewHolder. 在屏幕上的
這裏須要注意的是這個Cache,它雖然是緩存,可是它緩存效果和Scarp效果是同樣的。例如你的Cache是2,你上滑動出去後,下滑回來的兩個item是不會再進行onBindViewHolder的. 這裏另外提一點的是: 列表中item/廣告的impression統計.
不要在onBindViewHolder中設置監聽器,在onCreateViewHolder中設置監聽器.
LinearLayoutManager.setInitialPrefetchitemCount()
RecyclerView.setHasFixedSize()
何時用? 若是Adapter的數據變化不會致使RecyclerView的大小變化就能夠用 RecyclerView.setHasFixedSize(true)
多個RectclerView共用RecycledViewPool.
使用DiffUtil
1,畫分割線 2,高亮item 3,視覺上分組 recyclerview教程