一个很好的ListView的例子
网址是:
http://www.myandroidsolutions.com/2012/07/19/android-listview-with-viewholder-tutorial/
关键代码:
public class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mListItems;
private LayoutInflater mLayoutInflater;
public MyCustomAdapter(Context context, ArrayList<String> arrayList){
mListItems = arrayList;
//get the layout inflater
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
//getCount() represents how many items are in the list
return mListItems.size();
}
@Override
//get the data of an item from a specific position
//i represents the position of the item in the list
public Object getItem(int i) {
return null;
}
@Override
//get the position id of the item from the list
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
// create a ViewHolder reference
ViewHolder holder;
//check to see if the reused view is null or not, if is not null then reuse it
if (convertView== null) {</span>
holder = new ViewHolder();
convertView= mLayoutInflater.inflate(R.layout.list_item, null);
holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);
// the setTag is used to store the data within this view
convertView.setTag(holder);
} else {
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
}
//get the string item from the position "position" from array list to put it on the TextView
String stringItem = mListItems.get(position);
if (stringItem != null) {
if (holder.itemName != null) {
//set the item name on the TextView
holder.itemName.setText(stringItem);
}
}
//this method must return the view corresponding to the data at the specified position.
return convertView;
}
/**
* Static class used to avoid the calling of "findViewById" every time the getView() method is called,
* because this can impact to your application performance when your list is too big. The class is static so it
* cache all the things inside once it's created.
*/
private static class ViewHolder {
protected TextView itemName;
}
}
ListView的工作流程
ListView在开始绘制的时候,首先调用getCount()函数,根据它的返回值来获得ListView的长度。然后根据这个长度,调用getView逐渐绘制每一行。
可以看出getView是实现ListView的重点方法,该方法实现的是Adapter接口中getView方法
public abstract View getView(int position,View convertView,ViewGroup parent)
position:要从适配器中获得的视图位置
convertView:尽可能的重用旧视图,在使用之前必须检查是否为空以及是否是合适的类型,如果不能将视图转换正确显示数据,将会重新创建视图。
viewGroup 该视图最终会与指定位置的数据视图联系在一起。
好像还是不容易理解。
一个屏幕上只能显示有限的item,而其他可见的Item此时在Recycler中,这时候convertView为null。
当item1滚出屏幕时,一个新的Item从屏幕低端滚进来的时候,这时候convertView的值就不为空了,经测试,它的值恰好是滚出屏幕的item1的值。这样的话,就比较容易理解convertView了,就是当convertView中不为空,只需要设定新的数据,然后返回convertView的话,就不需要重新定义视图了。