Android 自学之列表视图ListView和ListActivity
ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项。
创建ListView有两种方式:
- 直接使用ListView创建。
- 让Activity继承ListActivity。
一旦在程序中获得ListView之后,接下来需要为ListView设置它要显示的列表项了。在这一点上,ListView与前面介绍的AutoComplete、Spinner类似,他们都需要一个供显示的列表项,这就需要借助于内容Adapter了,内容Adapter负责提供需要显示的列表项。
ListView的常用XML属性
XML属性 | 说明 |
android:choiceMode | 设置ListView的选择行为 |
android:divider | 设置list列表项的分隔条(既可用颜色分隔,也可用用Drawable分隔) |
android:dividerHeight | 设置分隔条的高度 |
android:entries | 指定一个数组资源,android将根据该数组资源来生成ListView |
android:footerDividersEnabled | 如果设置为false,则不在footer view之前绘制隔条 |
android:headerDividersEnabled | 如果设置为false,则不在header view之后绘制隔条 |
页面布局代码:layout/main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <!-- 直接使用数组资源给出列表项 --> 8 <ListView 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:entries="@array/books" 12 android:divider="@drawable/red" 13 android:headerDividersEnabled="false" 14 /> 15 <!-- 使用ArrayAdapter提供列表项的ListView --> 16 <ListView 17 android:id="@+id/list2" 18 android:layout_width="fill_parent" 19 android:layout_height="wrap_content" 20 android:divider="@drawable/green" 21 /> 22 </LinearLayout>
页面布局代码里面写了两个ListView,第一个通过android:entries指定了列表数组,第二个通过ArrayAdapter使用数组提供列表项。
1 package com.yangjing.arrayadapterlist; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.widget.ArrayAdapter; 6 import android.widget.ListView; 7 8 public class Arrayadapterlist extends Activity{ 9 10 @Override 11 protected void onCreate(Bundle savedInstanceState) { 12 // TODO Auto-generated method stub 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.main); 15 ListView list2 = (ListView)findViewById(R.id.list2); 16 //定义一个数组 17 String[] arr ={"小智", "小刚" , "大木博士"}; 18 //将数组包装ArrayAdapter 19 ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>( 20 this , android.R.layout.simple_list_item_1 , arr); 21 //为ListView设置Adapter 22 list2.setAdapter(arrayAdapter); 23 } 24 }
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this , android.R.layout.simple_list_item_1 , arr);
创建ArrayAdapter时必须指定一textViewResourceId,该参数决定每个列表项的外观形式。Android为该属性提供了如下属性值:
- simple_list_item_1:每一个列表项都是普通的textView
- simple_list_item_2:每一个列表项都是普通的textView(字体略大)
- simple_list_item_checked:每一个列表项都是一个已勾选的列表项
- simple_list_item_multiple_choice:每个列表项都是带多选框的文本
- simple_list_item_single_choice:每个列表项都是带多单选按钮的文本
最初运行的效果:
将上面创建的arrayadapter改为:ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
this , android.R.layout.simple_list_item_single_choice , arr);
效果如下:
实例:基于ListActivity实现列表
如果程序的窗口仅仅需要显示一个列表,则可以直接让Activity继承ListActivity来实现,ListActivity的子类无需调用setContentView()方法来显示某个界面,而是直接传入一个Adapter,ListActivity的类就呈现出一个列表。
比如下面的程序:
界面程序:main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <ListView android:id="@+id/android:list" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 android:background="#0000ff" 11 android:layout_weight="1" 12 android:drawSelectorOnTop="false"></ListView> 13 14 <!-- ① android:drawSelectorOnTop="true" 点击某一条记录,颜色会显示在最上面,记录上的文字被遮住,所以点击文字不放,文字就看不到 15 16 ② android:drawSelectorOnTop="false" 点击某条记录不放,颜色会在记录的后面,成为背景色,但是记录内容的文字是可见的 --> 17 </LinearLayout>
主java程序:ListActivityTest.java
1 package com.yangjing.listactivitytest; 2 3 import android.app.ListActivity; 4 import android.os.Bundle; 5 import android.widget.ArrayAdapter; 6 7 public class ListActivityTest extends ListActivity{ 8 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 //设置使用自己的界面 13 //setContentView(R.layout.main); 14 String[] arr = {"小狮","灵感","离","小黑","放生","灵"}; 15 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice,arr); 16 //设置窗口显示列表 17 setListAdapter(adapter); 18 } 19 20 }
效果如下:
使用SimpleAdapter创建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)绑定数据。 如果没有一个合适的绑定发生将会抛出IllegalStateException。
public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
参数:
- context:上下文,比如this。关联SimpleAdapter运行的视图上下文
- data:Map列表,列表要显示的数据,这部分需要自己实现,类型要与上面的一致,每条项目要与from中指定条目一致
- resource:ListView单项布局文件的Id,这个布局就是你自定义的布局了,你想显示什么样子的布局都在这个布局中。这个布局中必须包括了to中定义的控件id
- from:一个被添加到Map上关联每一个项目列名称的列表,数组里面是列名称
- to:是一个int数组,数组里面的id是自定义布局中各个控件的id,需要与上面的from对应
下面用个实例解释下SimpleAdapter的用法:
界面程序:main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <!-- 定义一个ListView --> 7 <ListView android:id="@+id/mylist" 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content"></ListView> 10 11 <!-- 定义一个ImageView,作为列表项的一部分 --> 12 <ImageView android:id="@+id/header" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:paddingLeft="10dp"/> 16 17 <!-- 定义一个TextView,用于作为列表项的一部分 --> 18 <TextView android:id="@+id/name" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:textSize="16dp" 22 android:gravity="center_vertical" 23 android:paddingLeft="10dp"/> 24 </LinearLayout>
主程序:SimpleAdapterTest.java
1 package com.yangjing.simpleadaptertest; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 8 import android.app.Activity; 9 import android.os.Bundle; 10 import android.widget.ListView; 11 import android.widget.SimpleAdapter; 12 13 public class SimpleAdapterTest extends Activity{ 14 15 //首先定义好name和头像 16 private String[] names = new String[]{"小狮","灵感","离","小黑"}; 17 18 private int[] imageIds = new int[]{R.drawable.tiger,R.drawable.nongyu,R.drawable.libai,R.drawable.qingzhao}; 19 20 @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.main); 24 25 //创建一个list集合,list集合元素是Map 26 List<Map<String, Object>> listItems = new ArrayList<Map<String,Object>>(); 27 28 for (int i = 0; i < names.length; i++) { 29 Map<String, Object> listItem = new HashMap<String, Object>(); 30 listItem.put("header", imageIds[i]); 31 listItem.put("personName", names[i]); 32 listItems.add(listItem); 33 } 34 35 SimpleAdapter simpleAdapter = new SimpleAdapter( 36 this, 37 listItems, 38 R.layout.main, 39 new String[]{"header","personName"}, 40 new int[]{R.id.header,R.id.name}); 41 ListView list = (ListView) findViewById(R.id.mylist); 42 //为ListView设置Adapter 43 list.setAdapter(simpleAdapter); 44 } 45 }
效果如下: