Android ListView

分享到:

ListView是Android开发中最常用的数据列表控件,ListView的每一行即可以显示文字又可以显示图片和按钮并且支持交互操作,开发者可以利用它开发出非常丰富的列表效果。当一屏显示不了全部信息时ListView控件支持上下滑动操作,要注意的是不到把ListView放到ScrollView当中因为这两个控件都支持上下滑动的滚动条,如果把这两种控件进行嵌套布局将会出现难以预料的结果。

完成一个ListView至少需要以下3个步骤:

1. 首先要有一个ListView控件,可以用XML来布局,也可以用java代码动态生成
2. 其次我们要准备好显示在ListView上的数据,可以是来自数据库的,也可以是来自其它数据源的。
3. 最后我们需要一个数据适配器把数据绑定到ListView上这样才能显示出列表效果,适配器分为三种:ArrayAdapter,SimpleAdapter和自定义的BaseAdapter其中ArrayAdapter是最简单的只能显示字符串,SimpleAdapter可以使ListView包含其它控件例如ImageView来显示图片,自定义BaseAdapter可以实现更为丰富的列表效果和交互体验。

先看一个最简单的ListView实例(环境:Android 4.0.3),代码如下:

package com.my.androidtest;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ListViewActivity extends Activity {
          
	//定义一个ListView对象
	private ListView listView;
  
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list_view);
  
		listView = new ListView(this);
		listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,setData()));
		setContentView(listView);
	}
  
	//为ListView准备的数据
	private List<String> setData(){
		List<String> data = new ArrayList<String>();
		data.add("数据1");
		data.add("数据2");
		data.add("数据3");
		data.add("数据4");
		data.add("数据5");
		data.add("数据6");
		return data;
	}
}        

ListView实例

简单分析一下这个例子,本例没有在Layout文件中进行XML布局,直接在java代码中生成ListView控件,如果用XML布局需要在java代码中使用this.findViewById(控件id)方法来初始化控件。

关键语句:
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,setData()));
通过上面这句代码完成了数据绑定。setAdapter的方法结构是这样的void android.widget.ListView.setAdapter(ListAdapter adapter)参数是一个ListAdapter类型的对像, 本例我们使用了ArrayAdapter,包含了3个参数,
第一个参数:"this"可以理解为上下文关系(context)
第二个参数:每行的布局文件,我们用了一个系统内置的列表样式"android.R.layout.simple_expandable_list_item_1"
第三个参数:数据, setData(),是自定义的方法,返回一个包含6条字符串数据的ArrayList
最后使用setContentView(listView)方法把ListView呈现出来
注意:如果用java动态生成控件要记得调用setContentView(控件实例对像)方法,否则控件会无法显示


包含图片并且有点击交互的ListView实例:

因为ArrayAdapter只能提供字符串显示,如果想在ListView中显示图片就不行了,所以这个例子要用到SimpleAdapter给ListView提供数据,分为以下几步:
1 定义ListView的行布局文件,并且给包含的子控件设置ID,这个布局文件相当于模版决定了ListView最终显示效果
2 构造一个包含图片的数据源,通常使用ArrayList<Map>类型,List的每一行都是一个HashMap对象,Map元素以键值对的方式存储并且支持Object因此可以存放包括图片在内各种类型的数据。
3 利用 SimpleAdapter 给行布局文件中的控件绑定数据
代码如下:

主界面的XML布局,非常简单在LinearLayout中只有一个ListVIew控件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/LinearLayout1"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical" >
  <ListView
          android:id="@+id/listView1"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" >
  </ListView>
</LinearLayout>

ListView行模板布局,水平方向摆放了ImageView和TextView, 也就是说ListView的每一行左侧显示图片右侧显示文字,这个文件保存为list_item.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/RelativeLayout1"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal" >

         <ImageView
          android:id="@+id/imageView1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentLeft="true"
          android:layout_alignParentTop="true"
          android:src="@drawable/ic_launcher" />

         <TextView
          android:id="@+id/textView1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignBottom="@+id/imageView1"
          android:layout_marginBottom="14dp"
          android:layout_marginLeft="16dp"
          android:layout_toRightOf="@+id/imageView1"
          android:text="TextView" />

</RelativeLayout>

java代码:

package com.my.androidtest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class ListView2 extends Activity {
          
	private ListView listView1;
	private ArrayList<Map<String,Object>> listData= new ArrayList<Map<String,Object>>();
	private String[] dataStr = { "数据1", "数据2", "数据3"};
  
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list_view2);
  
		listView1=(ListView)this.findViewById(R.id.listView1);
  
		int lengh = dataStr.length; 
		for(int i =0; i < lengh; i++) { 
			//创建HashMap对象,键名是String类型,值是Object类型
			Map<String,Object> item = new HashMap<String,Object>(); 

			//设置图片数据,本例直接引用了项目图标(绿色的小机器人),引用其它图片的方法是一样的
			item.put("image", R.drawable.ic_launcher); 

			//设置文本数据
			item.put("dataString", dataStr[i]);
			listData.add(item);
		} 
  
		SimpleAdapter adapter = new SimpleAdapter(this, listData, R.layout.list_item, new String[]{"image","dataString"}, new int[]{R.id.imageView1, R.id.textView1});
		
		listView1.setAdapter(adapter);
     
		//listview行点击事件
		listView1.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
				Toast.makeText(ListView2.this, "你点击了数据:"+dataStr[position], Toast.LENGTH_LONG).show();
			}   
		});

	}
}

运行效果如下图:

ListView实例

点击某一行会弹出一个Toast提示,如下图:

ListView实例

整个例子的关键在于理解行模板布局和数据之间的对应关系,
首先看ListView行模板布局list_item.xml这个文件,其中包含一个ImageView(ID为imageView1)和一个TextView(ID为textView1)
再看HashMap, 每组数据包含两个字段分别是"image"和"dataString"
imageView1对应字段"image",textView1对应字段"dataString",具体是怎么对应上的就要了解SimpleAdapter这个对像了,
SimpleAdapter的基本格式如下:
SimpleAdapter(Context, 数据, 行模版布局, 字段名数组, 行布局控件ID数组)
下面针对本例逐一说明这5个参数:
1 Context,通常使用this即可
2 数据, 本例对应变量listData,是一个包含HashMap的ArrayList
3 行模版布局,这个就是我们自定义的list_item.xml,做为参数布局文件导入都有特定格式,如本例:R.layout.list_item
4 字段名数组,这是一个String类型的数组,想把哪些字段显示出来就要把它们列举出来,如本例要显示"image"和"dataString"两个字段,所以相应代码是 new String[]{"image","dataString"}
5 行布局控件ID数组,这是一个int类型的数组,需要行布局中的哪些控件来绑定数据就要把对应的ID列举出来,如本例要在ImageView和TextView上分别绑定数据,所以代码是 new int[]{R.id.imageView1, R.id.textView1}
通过以上几个步骤就可以把数据与控件对应起来了,最后用setAdapter方法把adapter加载到ListView上就大功告成了。
最后给出了实现点击交互的事件setOnItemClickListener,其内部要覆写onItemClick方法,通过position参数能得到点击具体某一行的序号(从0开始)再配合已有数组就能得到对应的数据。

注意事项:字段名数组和行布局控件ID数组要遵循数量一致、顺序一致的原则,否则会出现问题。
例如本例:
String[]{"image","dataString"}
int[]{R.id.imageView1, R.id.textView1}
"image"对应imageView1,"dataString"对应textView1,系统会自动识别两个数组元素个数是否相等,并按顺序一一对应。形如:string[0]对应int[0], string[1]对应int[1] , .....。所以在书写字段名数组和控件ID数组这两个参数时要格外注意。

昵    称:
验证码:

相关文档:

Android控件
Android基础知识
Android组件
Android实例