RecyclerView详解
1:和Listview的不同:
1)Listview只支持纵向列表,RecyclerVeiw支持纵向、横向、网格以及瀑布流;
2)ListView是2级缓存机制,RecyclerView是4级缓存机制
3)ListView没有强制实现ViewHolder
2:ListView:
用法:
@Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.simple_item, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.merchant_name); holder.iv = (ImageView) convertView.findViewById(R.id.head); convertView.setTag(holder);//绑定ViewHolder对象 } else { holder = (ViewHolder) convertView.getTag();//取出ViewHolder对象 } holder.text.setText(listems.get(position)); holder.iv.setImageBitmap(imgId.get(position)); holder.text.setTag(position); holder.iv.setTag(convertView); return convertView; }
缓存机制:
1)屏幕内的view复用:屏幕每16ms刷新一次,需要重新绘制,item可以直接复用,不需要重新绑定数据,不执行getview
2)屏幕外的view复用:view的数据是脏数据,执行getView,传进来的convertView不为空,但是需要重新绑定数据
3)创建新的view:执行getView,传进来的convertView为空,需要创建新的view
ViewHolder:
1)ViewHolder的作用不是为了 复用,ListView、RecyclerView本身就有复用机制,不用ViewHolder,一样是复用view。
ViewHolder是为了避免过多的findViewById操作,这是需要消耗性能的
2)一个view对应一个ViewHolder
RecyclerView:
用法:
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.id_card_recyclerview_item_home, viewGroup, false)); return holder; } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { ((MyViewHolder) viewHolder).date.setText(context.getString(R.string.id_history_date) + ":" + idHistoryRecords.get(i).getDate()); ((MyViewHolder) viewHolder).time.setText(context.getString(R.string.id_history_time) + ":" + idHistoryRecords.get(i).getTime()); ((MyViewHolder) viewHolder).transactionNo.setText(idHistoryRecords.get(i).getTransactionNo()); }
缓存机制:4级:
1)屏幕内的vie复用,对应Listview的第一点,屏幕每16ms刷新一次,需要重新绘制,item可以直接复用,不需要重新绑定数据,不执行onCreateViewHolder和onBindViewHolder
2)超出屏幕外2个的item复用,可以直接复用,不需要重新绑定数据,不执行onCreateViewHolder和onBindViewHolder
3)RecyclerViewPool的view复用,默认5个,可以自行设置,是脏数据,需要重新绑定数据,执行onBindViewHolder
4)还有一级缓存不常用的,不研究
5)创建新的view,执行onCreateViewHolder
RecyclerViewPool:
ViewPager和RecyclerViewPool配合,可以最大程度对view进行复用,各个veiwPager里面的RecyclerView的item如果类型一样,就可以共用recyclerViewPool,
这样,当一个ViewPager切换到另外一个的时候,RecyclerView不需要重新create view,而是直接从RecyclerViewPool取出view复用
性能优化:
2)不要在onBindViewHolder里面设置监听,因为RecyclerViewPool复用的数据脏数据,会反复调用。应该在onCreteView里面设置监听,每个view肯定都会经历一次creatView,view和clicklistener一一对应,view和holder对应达到效果。
3)数据处理与视图绑定分离,去除onBindViewHolder方法里面的耗时操作,只做纯粹的数据绑定操作。当程序走到onBindViewHolder方法时,数据应当是准备完备的,禁止在onBindViewHolder方法里面进行数据获取的操作。
4)对于固定尺寸的item,可以使用setHasFixedSize
避免requestLayout