本文转自:http://blog.youkuaiyun.com/tianshuguang/article/details/7344315
重写ListVIew的BaseAdapter需要重写一下四个方法:
getCount()、getItem(int position)、getItemId(int position)以及getView(),其中最重要的是getView()方法。
@Override
public int getCount() {
// How many items are in the data set represented by this Adapter.
//(在此适配器中所代表的数据集中的条目数)
return 0;
}
@Override
public Object getItem(int i) {
// Get the data item associated with the specified position in the data set.
//(获取数据集中与指定索引对应的数据项)
return null;
}
@Override
public long getItemId(int i) {
// Get the row id associated with the specified position in the list.
//(取在列表中与指定索引对应的行id)
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
// Get a View that displays the data at the specified position in the data set.
return null;
}
其中最重要的处理就是getView:
第一种:没有任何处理。但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能。
@Override
public View getView(int i, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, null);
}
ImageView img = (ImageView)convertView.findViewById(R.id.img)
TextView title = (TextView)convertView.findViewById(R.id.title);
TextView info = (TextView)ConvertView.findViewById(R.id.info);
img.setImageResource(R.drawable.ic_launcher);
title.setText("Hello");
info.setText("world");
return convertView;
}
第二种ListView优化:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
convertView = mInflater.inflate(R.layout.list_item, null);
}
ImageView img = (ImageView)convertView.findViewById(R.id.img)
TextView title = (TextView)convertView.findViewById(R.id.title);
TextView info = (TextView)ConvertView.findViewById(R.id.info);
img.setImageResource(R.drawable.ic_launcher);
title.setText("Hello");
info.setText("world");
return convertView;
}
第三种ListView优化:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。
当我们判断 convertView == null 的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。(看下面代码中)
如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。
//在外面先定义,ViewHolder静态类
staticclass ViewHolder
{
public ImageView img;
public TextView title;
public TextView info;
}
//然后重写getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item, null);
holder.img = (ImageView)item.findViewById(R.id.img)
holder.title = (TextView)item.findViewById(R.id.title);
holder.info = (TextView)item.findViewById(R.id.info);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
holder.img.setImageResource(R.drawable.ic_launcher);
holder.title.setText("Hello");
holder.info.setText("World");
}
return convertView;
}
到这里,可能会有人问ViewHolder静态类结合缓存convertView与直接使用convertView有什么区别吗,是否重复了
在这里,官方给出了解释
提升Adapter的两种方法
To work efficiently the adapter implemented here uses two techniques: -It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
(译:重用缓存convertView传递给getView()方法来避免填充不必要的视图) -It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
(译:使用ViewHolder模式来避免没有必要的调用findViewById():因为太多的findViewById也会影响性能) ViewHolder类的作用 -The ViewHolder pattern consists in storing a data structure in the tag of the view returned by getView().This data structures contains references to the views we want to bind data to, thus avoiding calling to findViewById() every time getView() is invoked
(译:ViewHolder模式通过getView()方法返回的视图的标签(Tag)中存储一个数据结构,这个数据结构包含了指向我们
要绑定数据的视图的引用,从而避免每次调用getView()的时候调用findViewById())
2.RecyclerView
使用RecyclerView我们首先需要重写一个内部类ViewHolder,这个ViewHolder是继承自RecyclerView.ViewHolder。然后这个ViewHolder的构造函数中需要传入一个View的参数,这个参数通常就是RecyclerView子项的最外层布局,然后我们就可以获取到布局中子项的实例。
因为我们的HomeAdapter继承自RecyclerView.ViewHolder,所以必须重写onCreateViewHolder()、onBindViewHolder()以及getItemCount()这三个方法。
1)onCreateViewHolder():用于创建ViewHolder实例,将我们用到的布局加载进来,并且将加在进来的布局传入构造函数中去
2)onBindViewHolder():RecyclerView的子项进行赋值操作,他会在每个子项滚动到屏幕内的时候进行操作。
3)getItemCount():获取到RecyclerView共有多少个子项,直接返回数据源的长度。
直接上代码吧:
class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
{
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
MainActivity.this).inflate(R.layout.item_home, parent,
false));
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
holder.tv.setText(mDatas.get(position));
}
@Override
public int getItemCount()
{
return mDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView tv;
public MyViewHolder(View view)
{
super(view);
tv = (TextView) view.findViewById(R.id.id_num);
}
}
}
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mAdapter = new HomeAdapter());
这样就可以实现一个简单的RecyclerView的使用。