前面已经有了两种实现ListView的方法,分别是使用简单但功能单一的ArrayAdapter实现ListView,另一种是使用并不简单,功能还可以的SimpleAdapter实现ListView。接下来是第三种实现方法,使用扩展的BaseAdapter实现显示自定义列表项的ListView。
前面的两种Adapter都是继承了BaseAdapter,所以同样的,扩展BaseAdapter的用法就是自定义一个Adapter类继承BaseAdapter,接着需要重写以下4个方法:
getCount():该方法返回的是一个int类型变量,代表一共有多少个列表项
getItem(int position):该方法返回的是列表项position处的内容
getItemId(int position):返回的是posotion处item的id
getView(int position,View convertView,ViewGroup parent):返回的是posotion处的item
其中最重要的两个方法是getCount()方法和getView()方法,而当item的数量很大时,getView()方法又涉及到了一个优化的问题,这里暂且不提,只介绍最基本的用法。优化在后面的文章中会再有介绍。
首先惯例,在布局文件中定义一个ListView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/main_lv"></ListView>
</RelativeLayout>
该实例的Activity将会使用扩展的BaseAdapter来实现Adapter对象,代码如下:
public class MainActivity extends Activity {
//布局文件中的ListView
private ListView lv;
//ListView中显示的数据集合
private List<Bean> list;
//扩展的Adapter
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intiData();
intiView();
}
private void intiView() {
lv = (ListView) findViewById(R.id.main_lv);
adapter = new MyAdapter(this, list);
lv.setAdapter(adapter);
}
private void intiData() {
list = new ArrayList<Bean>();
Bean b1 = new Bean(R.drawable.a59, "孙悟空", "齐天大圣");
Bean b2 = new Bean(R.drawable.a60, "牛魔王", "混世魔王");
Bean b3 = new Bean(R.drawable.a61, "假悟空", "六耳猕猴");
list.add(b3);
list.add(b1);
list.add(b2);
}
}
这里为了存储每个列表项的数据,设计了一个Bean类:
public class Bean {
//item中的图片
private int icon_iv;
//item中的name
private String name_tv;
//item中的desc
private String desc_tv;
public Bean(int icon_tv,String name_tv,String desc_tv){
this.icon_iv = icon_tv;
this.name_tv = name_tv;
this.desc_tv = desc_tv;
}
}
这里的属性对应item布局中的每一项控件,item布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/item_iv"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/item_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
最重要的MyAdapter的代码如下:
public class MyAdapter extends BaseAdapter{
private Context context;
private List<Bean> list;
public MyAdapter(Context context,List<Bean> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(context, R.layout.item, null);
ImageView icon_iv = (ImageView)view.findViewById(R.id.item_iv);;
TextView name_tv = (TextView) view.findViewById(R.id.item_name);
TextView desc_tv = (TextView) view.findViewById(R.id.item_desc);
desc_tv.setText(list.get(position).getDesc_tv());
icon_iv.setImageResource(list.get(position).getIcon_iv());
name_tv.setText(list.get(position).getName_tv());
return view;
}
在getView()方法中通过View类的inflate方法找到item的布局并实现为对应的对象view,接着通过findViewById找到三个需要传入数据的控件,最后通过对应的方法为控件传入需要的值,返回的view就是已经设置了数据的View对象了。
本实例的效果如下: