之前介绍了三种
adapter:
ArrayAdapter<T>
、
SimpleAdapter和SimpleCursorAdapter。
使用android提供的
adapter来绘制列表的话,列表的每一项的显示都是一样的。为了实现
ListView的单双行不同颜色显示,需要自定义
adapter的子类。
adapter的常用子类有BaseAdapter、
ArrayAdapter、
SimpleAdapter等,下面介绍自定义
BaseAdapter和
ArrayAdapter的实现。
1.自定义
BaseAdapter
效果图如下:
在上一篇
《ListView(1)——各种Adapter的使用》
的基础上,为了实现
ListView的单双行不同颜色显示,需要自定义
adapter的子类,而
activity_main.xml文件和list_item.xml
文件都不需要更改,MainActivity.java代码修改如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 图片资源的ID
int[] images = new int[] { R.drawable.item_img_a,
R.drawable.item_img_b, R.drawable.item_img_c,
R.drawable.item_img_d, R.drawable.item_img_e };
List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < 5; i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemImage", images[i]);
map.put("ItemTitle", "This is Title " + i);
map.put("ItemText", "This is text " + i);
data.add(map);
}
// 绑定XML中的ListView,作为Item的容器
ListView listView = (ListView) findViewById(R.id.list);
MyBaseAdapter adapter = new MyBaseAdapter(MainActivity.this, data);
listView.setAdapter(adapter);
}
下面我们实现自定义的My
BaseAdapter类。
My
BaseAdapter类继承自
BaseAdapter类,
BaseAdapter为抽象类,继承它需要实现如下方法,因此具有较高的灵活性。
public class MyBaseAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null;
}
}
ListView
在绘制时首先会
调用
getCount()
方法得到绘制次数
,然后
通过
getView()
方法一层一层进行绘制,
所以我们可以在
getView()
方法中根据
position(
当前绘制的
ID)
来的修改绘制内容。
而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。
public class MyBaseAdapter extends BaseAdapter {
private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 };
private Context mContext;
private List<HashMap<String, Object>> dataList;
public MyBaseAdapter(Context context, List<HashMap<String, Object>> dataList) {
this.mContext = context;
this.dataList = dataList;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public HashMap<String, Object> getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(
R.layout.list_item, null);
holder.image = (ImageView) convertView.findViewById(R.id.ItemImage);
holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);
holder.text = (TextView) convertView.findViewById(R.id.ItemText);
// 将holder绑定到convertView
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 向ViewHolder中填入的数据
holder.image.setImageResource((Integer) getItem(position).get(
"ItemImage"));
holder.title.setText((String) getItem(position).get("ItemTitle"));
holder.text.setText((String) getItem(position).get("ItemText"));
int colorPos = position % colors.length;
convertView.setBackgroundColor(colors[colorPos]);
return convertView;
}
/**
* ViewHolder类用以储存item中控件的引用
*/
final class ViewHolder {
ImageView image;
TextView title;
TextView text;
}
}
getView()
方法用来获得绘制每个
item
的View对象,如果
每次
getView()
被执行都new出一个View对象,长此以往会产生很大的消耗,特别当item中还有Bitmap等,甚至会造成OOM的错误导致程序崩溃。从上面的代码可以看到
getView()
有一个convertView参数,这个参数用来缓存View对象。当ListView滑动的过程中,会有item被滑出屏幕而不再被使用,这时候Android会回收这个item的view,这个view也就是这里的convertView。这样如果convertView不为null,就不用new出一个新的View对象,只用往convertView中填充新的item,这样就省去了new View的大量开销。
在上面的代码中,在缓存convertView减少
new View开销的同时,通过setTag()方法将数据结构
ViewHolder绑定到
convertView,从而
利用ViewHolder存储convertView中控件对象的引用,这样避免每次调用findViewById()方法。
2.自定义
ArrayAdapter<T>
在开发中需要将对象显示在listview中,这时候使用
ArrayAdapter<T>来显示指定对象类型。下面
自定义
ArrayAdapter<T>实现
上一节中自定义
BaseAdapter
实现的同样的效果,首先定义要显示的对象,代码如下ItemBean.java。
public class ItemBean {
private int image;
private String title;
private String text;
public ItemBean(int image, String title, String text) {
this.image = image;
this.title = title;
this.text = text;
}
public int getImage() {
return image;
}
public String getTitle() {
return title;
}
public String getText() {
return text;
}
}
和上一节一样,为了实现
ListView的单双行不同颜色显示,需要自定义
adapter的子类,而
activity_main.xml文件和list_item.xml
文件都不需要更改,MainActivity.java代码修改如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 图片资源的ID
int[] images = new int[] { R.drawable.item_img_a,
R.drawable.item_img_b, R.drawable.item_img_c,
R.drawable.item_img_d, R.drawable.item_img_e };
ArrayList<ItemBean> data = new ArrayList<ItemBean>();
for (int i = 0; i < 5; i++) {
ItemBean itemBean = new ItemBean(images[i], "This is Title " + i,
"This is text " + i);
data.add(itemBean);
}
// 绑定XML中的ListView,作为Item的容器
ListView listView = (ListView) findViewById(R.id.list);
MyArrayAdapter adapter = new MyArrayAdapter(MainActivity.this,
R.layout.list_item, data);
listView.setAdapter(adapter);
}
接下来自定义继承自
ArrayAdapter<
ItemBean
>
的
MyArrayAdapter类,
继承
ArrayAdapter<
ItemBean
>只需要重写getView()方法就可以实现与上一节相同的效果,并且不用保存List
<
ItemBean
>对象引用。
public class MyArrayAdapter extends ArrayAdapter<ItemBean> {
private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 };
private Context mContext;
private int resource;
public MyArrayAdapter(Context context, int resource, List<ItemBean> data) {
super(context, resource, data);
this.mContext = context;
this.resource = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(resource, null);
holder.image = (ImageView) convertView.findViewById(R.id.ItemImage);
holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);
holder.text = (TextView) convertView.findViewById(R.id.ItemText);
// 将holder绑定到convertView
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 向ViewHolder中填入的数据
holder.image.setImageResource(getItem(position).getImage());
holder.title.setText(getItem(position).getTitle());
holder.text.setText(getItem(position).getText());
int colorPos = position % colors.length;
convertView.setBackgroundColor(colors[colorPos]);
return convertView;
}
/**
* ViewHolder类用以储存item中控件的引用
*/
final class ViewHolder {
ImageView image;
TextView title;
TextView text;
}
}
参考文章:
http://www.open-open.com/lib/view/open1339485728006.html