ListView是手机系统中非常常用的一个组件,以垂直列表的形式显示所有列表项,今天我们来探索一下吧。
首先我们来了解一下ListView的基本属性吧。

XML属性
andorid:divider:设置List列表项的分隔条(既可用颜色分隔,也可用Drawable分隔)
android:dividerHeight:设置分隔条的高度
android:entries:设置一个数组资源,Android将根据该数组资源来生成ListView
android:footerDividersEnabled:如果设置为false,则不在footer View之前绘制分隔条
android:headerDividersEnabled:如果设置为false,则不在headerView之后绘制分隔条

接下来通过一个非常简单的案例来体验一下(使用Android Studio):
activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/hero"
        android:divider="#ff93ff87"
        android:dividerHeight="2px"
        android:headerDividersEnabled="false">
        </ListView>

</LinearLayout>

这里在values文件夹下加了一个arrays.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="books">
        <item>乔布斯</item>
        <item>拉里.佩奇</item>
        <item>谢尔盖</item>
        <item>扎克伯格</item>
    </string-array>
</resources>

真机上效果如下:

ListView android 设置默认选中ArrayAdapter android listview属性_ide

然而用数组的方式还不是太简单了呢?给人的感觉不够酷。如果想要对ListView的外观、行为进行定制,就需要把ListView作为AdapterView使用,通过Adapter控制每个列表项的外观和行为。现在你会问:什么是AdapterView了吧?
AdapterView的本质是容器,继承了ViewGroup。如上例,AdapterView可以包括多个列表项,更重要的是,可将多个列表项以合适的形式来现实,合适的形式就是我们要的炫酷的效果。而AdapterView显示的多个列表项由Adapter提供,调用AdapterView中的setAdapter(Adapter)方法即可。
那Adapter又是个什么东西呢?
Adapter本身是一个接口,派生了ListAdapter和SpinnerAdapter两个子接口。而非常常见的BaseAdapter实现了ListAdapter和SpinnerAdapter两个接口。我们常用的ArrayAdapter和SimpleAdapter都实现了BaseAdapter的接口。现在我们介绍一下ArrayAdapter常用的实现类吧。
ArrayAdapter:简单、易用,通常用于将List集合的多个值包装成多个列表项。
SimpleAdapter:并不简单、功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。
SimpleCursorAdapter:与SimpleAdapter基本相似,只是用于包装Cursor提供的数据。
BaseAdapter:通常用于被扩展,扩展BaseAdapter可以对各列表项进行最大限度的定制。
是不是有点晕了呢?接下来我们通过一个实例来理解。
activity_main.xml

<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/listfirst"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="#f00"
        android:dividerHeight="2px"
        android:headerDividersEnabled="false"></ListView>
</LinearLayout>

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private ListView listFirst;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listFirst = (ListView) findViewById(R.id.listfirst);
        String[] arr = {"乔布斯", "周星驰", "周杰伦"};
        //将数组包装成ArrayAdapter
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.array_item, arr);
        //为ListView设置Adapter
        listFirst.setAdapter(adapter);
    };
}

array_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/TextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"    
    android:textSize="24dp"
    android:padding="10px"
    android:shadowColor="#f0f"
    android:shadowDx="4"
    android:shadowDy="4"
    android:shadowRadius="2"/>

真机效果如下:

ListView android 设置默认选中ArrayAdapter android listview属性_xml_02

当然也可以直接集继承ListActivity啦,那样无需使用布局文件。

public class MainActivity extends ListActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] arr = {"乔布斯", "周星驰", "周杰伦"};
        //创建ArrayAdapter对象
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.checked_item, arr);
        setListAdapter(adapter);
    }
}

相信看到上面的代码,对这行代码肯定有疑问。
ArrayAdapter adapter = new ArrayAdapter(this, R.layout.checked_item, arr);
第一个参数(Context):它代表了访问整个Android应用的接口。几乎创建所有组件都需要传递进来Context对象。
第二个参数(textViewResourceId):一个资源ID,该资源ID代表一个TextView,该TextView将作为ArrayAdapter的列表项组件。
第三个参数(数组或List):为多个列表项提供数据。

是不是很简单呢?但是觉得还是太单调,接下来我们继续SimpleAdapter的学习。

activity_mai.xml

<LinearLayout 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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView 
        android:id="@+id/mylist"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"></ListView>

</LinearLayout>

然后我们设置Item的样子。
simple_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<!-- 定义一个ImageView,用于作为列表项的一部分。 -->
<ImageView android:id="@+id/header"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:paddingLeft="10dp"
    />
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<!-- 定义一个TextView,用于作为列表项的一部分。 -->
<TextView android:id="@+id/name"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:textSize="20dp"
    android:textColor="#f0f"
    android:paddingLeft="10dp"
    />
<!-- 定义一个TextView,用于作为列表项的一部分。 -->
<TextView android:id="@+id/desc"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:textSize="14dp"
    android:paddingLeft="10dp"
    />
</LinearLayout>
</LinearLayout>

MainActivity如下:

package com.example.simpleadapter;

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

import android.app.Activity;
import android.net.LocalSocketAddress.Namespace;
import android.os.Bundle;
import android.renderscript.Int2;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {

    private String[] names = new String[]{"小明", "小红", "小兰"};
    private String[] descs = new String[]
            {
                "小学生", "中学生", "大学生"
            };
    private int[] imageIds = new int[]{
        R.drawable.ic_launcher, R.drawable.ic_launcher,
        R.drawable.ic_launcher
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建一个List集合,List集合的元素是Map
        List<Map<String, Object>> listItems = new ArrayList<Map<String,Object>>();
        for(int i = 0; i < names.length; i++)
        {
            Map<String, Object> listItem = new HashMap<String, Object>();
            listItem.put("header", imageIds[i]);
            listItem.put("personName", names[i]);
            listItem.put("desc", descs[i]);
            listItems.add(listItem);
        }
        //创建一个SimapleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,
                R.layout.simple_item,
                new String[]{"personName", "header", "desc"},
                new int[]{R.id.name, R.id.header, R.id.desc});
        ListView list = (ListView) findViewById(R.id.mylist);
        //为ListView设置Adapter
        list.setAdapter(simpleAdapter);
        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), "被点击了", Toast.LENGTH_SHORT).show();

            }

        });
        list.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), "被选中了", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // TODO Auto-generated method stub

            }
        });

    }
}

真机效果如下:

ListView android 设置默认选中ArrayAdapter android listview属性_android_03

使用SimpleAdapter需要五个参数,如下:
第一个参数(Context):它代表了访问整个Android应用的接口。几乎创建所有组件都需要传递进来Context对象。
第二个参数:该参数是一个类型的集合对象,该集合中每个Map对象生成一个列表项。
第三个参数:该参数指定一个界面布局的ID。
第四个参数:该参数是一个int[]类型的参数,该参数决定提取Map对象中哪些key对应的value来生成列表项。
第五个参数:该参数是一个int[]类型的参数,该参数决定填充哪些组件。

接下来我们继续学习,扩展BaseAdapter实现不存储列表项的ListView。扩展BaseView可以取得对Adapter最大的控制权。
activity_main.xml

<LinearLayout 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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView 
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>

</LinearLayout>

MainActivity.java

package com.example.baseadaptertest1;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

    private  ListView myList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myList = (ListView) findViewById(R.id.myList);
        BaseAdapter adapter = new BaseAdapter() {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                //创建一个LinearLayout,并向其中添加两个组件
                LinearLayout line = new LinearLayout(MainActivity.this);
                line.setOrientation(0);
                ImageView image = new ImageView(MainActivity.this);
                image.setImageResource(R.drawable.ic_launcher);
                TextView text = new TextView(MainActivity.this);
                text.setText("第" + (position +1) + "个列表项");
                text.setTextSize(20);
                text.setTextColor(Color.RED);
                line.addView(text);
                //返回LinearLayout实例
                return line;
            }

            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return position;
            }

            @Override
            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public int getCount() {
                // 指定一共包含20项
                return 20;
            }
        };
        myList.setAdapter(adapter);
    }
}

真机效果如下:

ListView android 设置默认选中ArrayAdapter android listview属性_ide_04

该案例创建了一个BaseAdapter对象,扩展该对象需要重写如下四个方法:
getCount():该方法的返回值控制该Adapter将会包含多少个列表项。
getItem(int position):该方法的返回值决定第position处的列表项的内容。
getItemId(int position):该方法的返回值决定第position处的列表项的ID。
getView(int position, View convertView, ViewGroup parent):该方法的返回值决定第position处的列表项组件。
这里通过四种方法实现了Adapter。