吐槽:一直想写一篇完整的,能系统地介绍某个知识点的文章,但由于技术不够加上懒,只能仰望其他大神写出的非常优秀的文章,从中学习一二。今天看了hongyang大神写的关于recycleview的博客,获益良多啊!不过鸿神可能要全面解析这个控件,没那么多篇幅来写一些原理问题,所以我google了一番结合listview来介绍他们的优化原理(作为初学者,我仅凭自己理解去写这篇文章,如有错误,你来打我啊(开玩笑...),还是非常希望各位能及时帮我更正)
首先我们来看下,没有优化过的listview中getView方法(因为是介绍原理问题,所有的代码就不贴上了,百度一大堆)
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//listview_item里只有一个textview
View view = View.inflate(MainActivity.this, R.layout.listview_item,
null);
//使用每一次都findviewById的方法来获得listview_item内部的组件
TextView tv_item = (TextView) view.findViewById(R.id.tv_item);
tv_item.setText(list.get(position));
return view;
}
当我们的item有十几个的时候,手机屏幕不足以完全显示(说iphone18的走开!!),所以我们要向上滑动以显示下面其他的item,但这时前面的item就会淡出屏幕,再向下滑动,又显示前面的item了,但你会发现,无论显示第一个item还是显示最后一个item,只要出现在屏幕上一次,就会调用一次getView来创建这个item。这无疑是很浪费内存的,所以就有下面的优化方案。
public View getView(int position, View convertView, ViewGroup parent) {
View view;
ViewHolder holder;
// 判断convertView的状态,来达到复用效果
if (null == convertView) {
// 如果convertView为空,则表示第一次显示该条目,需要创建一个view
view = View.inflate(MainActivity.this, R.layout.listview_item,
null);
//新建一个viewholder对象
holder = new ViewHolder();
//将findviewbyID的结果赋值给holder对应的成员变量
holder.tvHolder = (TextView) view.findViewById(R.id.tv_item);
// 将holder与view进行绑定
view.setTag(holder);
} else {
// 否则表示可以复用convertView
view = convertView;
holder = (ViewHolder) view.getTag();
}
// 直接操作holder中的成员变量即可,不需要每次都findViewById
holder.tvHolder.setText(list.get(position));
return view;
}
convertView这个参数设计非常巧妙,是用来储存那些被你万恶的手指滑动导致淡出的item,当它为空,说明之前没有被创建过,所以就创建这个item,它不为空时,嘿嘿,说明是被淡出的item,之前有被创建,那就直接拿出来用就行啦。关于ViewHolder很多资料也有介绍,这里也不再赘述了。来看下图更有利于理解:
上面是ListView的。接下来我们来看下RecycleView:
package com.example.q_recycler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
/**
* Created by 强强 on 2017/2/6.
*/
public class MyRecycleviewAdapter extends RecyclerView.Adapter<MyRecycleviewAdapter.ViewHolder>{
List<String> list;
public MyRecycleviewAdapter(List<String> list){
this.list=list;
}
@Override
public MyRecycleviewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.id_num,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tv.setText(list.get(position));
}
@Override
public int getItemCount() {
if(list!=null) return list.size();
else
return 0;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView tv;
public ViewHolder(View itemView) {
super(itemView);
tv= (TextView) itemView.findViewById(R.id.id_num);
}
}
}
RecycleView作为ListView的升级版,自然有它的优势,抛弃那n多的功能(被鸿神称为艺术般的控件),它的内存优化也是独到的哦。
我的理解是:RecycleView提供了一个缓存机制,当一个item没有被创建时,就会调用onCreateViewHolder的方法创建这个item,同时也放入到缓存中,以ViewHolder的形式返回,当要显示item时,就会在缓存中寻找有没有创建过这个item,如果创建了的话就直接调用onBindViewHolder方法进行渲染显示。这里也避免重复创建item了,可见,它们的优化原理是相差无几的,结合起来更能让人理解。
结束语:这又是一片简文(好符合简书哦),文中只介绍了我对于这两个控件的一点点见解(个人理解),不敢肯定百分百是对的。还有,文中还有很多东西没有介绍到,因为我认为很多大神都对它们有非常详细的博客(懒),随便一搜就可以看到了,我再写的话,,,会很累的!!!!哈哈,下面贴两个详解博客吧
http://blog.csdn.net/skykingf/article/details/50827141