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复用

 

性能优化:

1).合理设置RecyclerViewPool的大小。如果一屏的item较多,那么RecyclerViewPool的大小就不能再使用默认的5,可适度增大Pool池的大小。如果存在RecyclerView中嵌套RecyclerView的情况,可以考虑复用RecyclerViewPool缓存池,减少开销

2)不要在onBindViewHolder里面设置监听,因为RecyclerViewPool复用的数据脏数据,会反复调用。应该在onCreteView里面设置监听,每个view肯定都会经历一次creatView,view和clicklistener一一对应,view和holder对应达到效果。

3)数据处理与视图绑定分离,去除onBindViewHolder方法里面的耗时操作,只做纯粹的数据绑定操作。当程序走到onBindViewHolder方法时,数据应当是准备完备的,禁止在onBindViewHolder方法里面进行数据获取的操作。

4)对于固定尺寸的item,可以使用setHasFixedSize避免requestLayout

posted @ 2022-12-21 08:23  蜗牛攀爬  阅读(291)  评论(0编辑  收藏  举报