ListView是我们在Android应用开发中常用的组件,它通过列表的形式展示数据,具有很强的可扩展性,通常使用还会给每一项绑定一个点击时间,用于处理相应的请求,ListView在电商的商品列表中是必不可少的,下面我们介绍几种常用的使用方法。
列表的显示需要三个元素:
1.ListVeiw 用来展示列表的View。
2.适配器 用来把数据映射到ListView上的中介。
3.数据 具体的将被映射的字符串,图片,或者基本组件。
android中我们常用的有3中不同的适配器,分别是:
1.ArrayAdapter 使用最为简单,以数据集合为基础,只显示一行文本。
2.SimpleAdapter 具有很好的扩种行,可以自定义出各种各样的布局。
3.SimpleCursorAdapter 可以方便的把数据库的内容通过列表的形式展现出来
另外,我们通常自己写一个继承自BaseAdapter(基础适配器)的适配器,用于将设计思路更加的符合规范,数据与视图分离开来,像MVC一样。
下面我们逐一介绍着几种方式:
(一)、ArrayAdapter适配器
ArrayAdapter可以实现简单的数据与ListView的绑定,我们逐步实现ListView。
1、在布局文件中加入一个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:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、在Activity中分别获取列表、数据、适配器。
- public class MainActivity extends Activity {
- private ListView myListView;//列表
- private List<String> itemList;//数据
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initData();
- myListView = (ListView) findViewById(R.id.listView);
- //ArrayAdapter中有三个参数
- //Context context 指定现在的上下文
- //int textViewResourceId 指定一个包含textview的布局文件,显示每行的信息
- //List<String> objects 在listview上显示的数据信息
- ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(MainActivity.this,
- android.R.layout.simple_list_item_1, itemList);//适配器
- }
- public void initData() {
- itemList = new ArrayList<String>();
- for (int i = 0; i < 20; i++) {
- itemList.add("测试数据" + i);
- }
- }
- }
3、看一下实现的效果

可以看到,listView中的每一项都只显示了一行信息,这种适配器,在需要显示每项内容只有一个时比较常用,一般我们的listView中每项都有较多的内容,所以还需要更加充实的适配器。
(二)、SimpleAdapter适配器
这是一个简单的适配器,可以将静态数据映射到XML文件中定义好的视图。你可以指定由Map组成的List(比如ArrayList)类型的数据。在ArrayList中的每个条目对应List中的一行。Maps包含每一行的数据。你可以指定一个XML布局以指定每一行的视图,根据Map中的数据映射关键字到指定的视图。绑定数据到视图分两个阶段,首先,如果设置了SimpleAdapter.ViewBinder,那么这个设置的ViewBinder的setViewValue(android.view.View, Object, String)将被调用。如果setViewValue的返回值是true,则表示绑定已经完成,将不再调用系统默认的绑定实现。如果返回值为false,视图将按以下顺序绑定数据:
• 如果View实现了Checkable(例如CheckBox),期望绑定值是一个布尔类型。
• TextView.期望绑定值是一个字符串类型,通过调用setViewText(TextView, String)绑定。
• ImageView,期望绑定值是一个资源id或者一个字符串,通过调用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)绑定数据。
• 如果View实现了Checkable(例如CheckBox),期望绑定值是一个布尔类型。
• TextView.期望绑定值是一个字符串类型,通过调用setViewText(TextView, String)绑定。
• ImageView,期望绑定值是一个资源id或者一个字符串,通过调用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)绑定数据。
如果没有一个合适的绑定发生将会抛出IllegalStateException。
1、在布局文件中加入一个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:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、自定义一个ListView每一项的布局,里面放一个图片和两个文本。
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/white" >
- <ImageView
- android:id="@+id/item_image"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@drawable/bank_boc" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/item_image"
- android:layout_marginLeft="10dp"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/item_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="标题"
- android:textColor="#000"
- android:textSize="25sp" />
- <TextView
- android:id="@+id/item_data"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="内容"
- android:textColor="#222"
- android:textSize="20sp" />
- </LinearLayout>
- </RelativeLayout>
效果如下:

3、在Activity中使用SimpleAdapter
- public class SimpleAdapterListActivity extends Activity {
- private ListView myListView;
- private List<HashMap<String, Object>> data;
- private final String TITLE = "title";
- private final String IMAGE = "image";
- private final String DATA = "data";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- myListView = (ListView) findViewById(R.id.listView);
- initData();
- // 参数:
- // context SimpleAdapter关联的View的运行环境
- // data 一个Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应该包含所有在from参数中指定的键
- // resource 一个定义列表项的布局文件的资源ID。布局文件将至少应包含那些在to中定义了的ID
- // from 一个将被添加到Map映射上的键名
- // to 将绑定数据的视图的ID,跟from参数对应,这些应该全是TextView
- SimpleAdapter simAdapter = new SimpleAdapter(
- SimpleAdapterListActivity.this, data, R.layout.item_listsimple,
- new String[] { TITLE, DATA, IMAGE }, new int[] {
- R.id.item_title, R.id.item_data, R.id.item_image });
- myListView.setAdapter(simAdapter);
- }
- public void initData() {
- data = new ArrayList<HashMap<String, Object>>();
- for (int i = 0; i < 20; i++) {
- HashMap<String, Object> mapItem = new HashMap<String, Object>();
- mapItem.put(TITLE, "标题" + i);
- mapItem.put(DATA, "介绍" + i);
- switch (i % 3) {
- case 0:
- mapItem.put(IMAGE, R.drawable.bank_boc);
- break;
- case 1:
- mapItem.put(IMAGE, R.drawable.bank_fjnx);
- break;
- case 2:
- mapItem.put(IMAGE, R.drawable.bank_visa);
- break;
- default:
- break;
- }
- data.add(mapItem);
- }
- }
- }
4、看一下效果

(三)、SimpleCursorAdapter适配器
SimpleCursorAdapter是android中专门为连接数据库与视图产生的,我们下面测试下使用SimpleCursorAdapter取到手机中的联系人。
1、在布局文件中加入一个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:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、在Activity中添加相应代码
- public class SimpleCursorActivity extends Activity {
- private ListView myListView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- myListView = (ListView)findViewById(R.id.listView);
- @SuppressWarnings("deprecation")
- Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
- startManagingCursor(cursor);
- ListAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{People.NAME}, new int[]{android.R.id.text1});
- myListView.setAdapter(listAdapter);
- }
- }
3、读取联系人要用到权限,在AndroidMenifest.xml中添加权限
- <uses-permission android:name="android.permission.READ_CONTACTS"/>
4、在模拟器中加入一条联系人数据,可以看到运行后效果

(四)、自定义适配器
在我们实际的应用中,通常使用自定义适配器,自定义适配器继承BaseAdapter,下面我们使用自定义的Adapter来实现(二)中介绍的SimpleAdapter的效果,
1、Activity的界面文件
- <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:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、ListView每一项的布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/white" >
- <ImageView
- android:id="@+id/item_image"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@drawable/bank_boc" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/item_image"
- android:layout_marginLeft="10dp"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/item_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="标题"
- android:textColor="#000"
- android:textSize="25sp" />
- <TextView
- android:id="@+id/item_data"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="内容"
- android:textColor="#222"
- android:textSize="20sp" />
- </LinearLayout>
- </RelativeLayout>
3、定义一个java类,用来存放在listItem中的每项数据
- public class ListItemModel {
- private String title;
- private String data;
- private int rid;
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getData() {
- return data;
- }
- public void setData(String data) {
- this.data = data;
- }
- public int getRid() {
- return rid;
- }
- public void setRid(int rid) {
- this.rid = rid;
- }
- }
4、自定义适配器
- public class MyListAdapter extends BaseAdapter {
- private List<ListItemModel> listItems;
- private LayoutInflater layoutInflater;
- public MyListAdapter(Context context) {
- layoutInflater = LayoutInflater.from(context);
- }
- public List<ListItemModel> getListItems() {
- return listItems;
- }
- public void setListItems(List<ListItemModel> listItems) {
- this.listItems = listItems;
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return listItems.size();
- }
- @Override
- public Object getItem(int position) {
- // 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
- ListItemView myListItemView;
- if (convertView == null) {
- myListItemView = new ListItemView();
- convertView = layoutInflater
- .inflate(R.layout.item_listsimple, null);
- myListItemView.setTv_title((TextView) convertView
- .findViewById(R.id.item_title));
- myListItemView.setTv_data((TextView) convertView
- .findViewById(R.id.item_data));
- myListItemView.setIv_image((ImageView) convertView
- .findViewById(R.id.item_image));
- convertView.setTag(myListItemView);
- } else {
- myListItemView = (ListItemView) convertView.getTag();
- }
- myListItemView.getTv_title()
- .setText(listItems.get(position).getTitle());
- myListItemView.getTv_data().setText(listItems.get(position).getData());
- myListItemView.getIv_image().setImageResource(
- listItems.get(position).getRid());
- return convertView;
- }
- class ListItemView {
- private TextView tv_title;
- private TextView tv_data;
- private ImageView iv_image;
- public TextView getTv_title() {
- return tv_title;
- }
- public void setTv_title(TextView tv_title) {
- this.tv_title = tv_title;
- }
- public TextView getTv_data() {
- return tv_data;
- }
- public void setTv_data(TextView tv_data) {
- this.tv_data = tv_data;
- }
- public ImageView getIv_image() {
- return iv_image;
- }
- public void setIv_image(ImageView iv_image) {
- this.iv_image = iv_image;
- }
- }
- }
5、Activity中添加数据和适配器,并与ListView绑定
- public class MyAdapterActivity extends Activity {
- private ListView listView;
- private String[] str_titles = { "自定义标题1", "自定义标题2", "自定义标题3", "自定义标题4",
- "自定义标题5", "自定义标题6", "自定义标题7", "自定义标题8", "自定义标题9" };
- private String[] str_datas = { "我的内容1", "我的内容2", "我的内容3", "我的内容4", "我的内容5",
- "我的内容6", "我的内容7", "我的内容8", "我的内容9" };
- private int[] rids = { R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa, R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa, R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa };
- private List<ListItemModel> myListItems;
- private MyListAdapter adapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- listView = (ListView) findViewById(R.id.listView);
- myListItems = new ArrayList<ListItemModel>();
- initData();
- adapter = new MyListAdapter(MyAdapterActivity.this);
- adapter.setListItems(myListItems);
- listView.setAdapter(adapter);
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // TODO Auto-generated method stub
- Toast.makeText(MyAdapterActivity.this, "点击了" + position, 1000)
- .show();
- }
- });
- }
- public void initData() {
- for (int i = 0; i < str_titles.length; i++) {
- ListItemModel lm = new ListItemModel();
- lm.setTitle(str_titles[i]);
- lm.setData(str_datas[i]);
- lm.setRid(rids[i]);
- myListItems.add(lm);
- }
- }
- }
6、看一下实现的效果
