Android UI - AdapterView 及其子类

AdapterView

  1. AdapterView 是一个抽象类,其派生的子类在用法上十分相似;
  2. AdapterView 继承了 ViewGroup;
  3. AdapterView 及其子类的继承关系如下:


  4. AdapterView 常用的实现类:
  • Spinner: 列表选择框,当需要用户选择的时候,可以提供一个列表将所有可选项列出来,供用户选择。
  • ListView: 以垂直列表的形式显示所有列表项。
  • GridView: 用于在界面上按行和列分布的方式来显示多个组件。

Adapter 接口及其实现类

  1. Adapter 是一个接口,其派生了 ListAdapter 和 SpinnerAdapter 两个子接口。其中,ListAdapter 为 AbsListView 提供列表项,而 SpinnerAdapter 为AbsSpinner 提供列表项;
  2. Adapter 及其实现类的继承关系如下:


  3. Adapter 常用的实现类:
  • ArrayAdapter: 通常用于将数组或 List 集合的多个值包装成多个列表项。
  • SimpleAdapter: 用于将 List 集合的多个对象包装成多个列表项。
  • SimpleCursorAdapter: 与 SimpleAdapter 类似,与数据库打交道。
  • Base Adapter: 抽象类,通常用于被继承,可以对个列表项进行最大限度的定制。

Adapter 浅谈


ArrayAdapter

ArrayAdapter(Context context, int resource, int textViewResourceId)

ArrayAdapter 三个参数说明:

  • context:整个应用的上下文
  • resource:界面布局 ID,代表一个布局样式文件,控制列表项的外观,此样式文件只能有一个 TextView,连 Layout 也不能有;可以使用系统自带的样式文件(android.R.layout.xxx),也可以使用自定义的样式文件(R.layout.xxx)
  • textViewResourceId:列表项中的数据

SimpleAdapter

SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

SimpleAdapter 五个参数说明:

  • context:整个应用的上下文
  • data: List<? extends Map<String, ?>> 类型的集合对象,集合中每个 Map<String, ?> 对象生成一个列表项
  • resource:界面布局 Id,代表一个布局样式文件,该文件作为列表项的组件,控制列表项的外观
  • from:String[] 类型的参数,该参数决定提取 Map<String, ?> 对象中哪些 key 对应的 value 来生成列表项
  • to:int[] 类型的参数,该参数决定使用自定义布局中的哪些 View 组件来组合成一个列表项(数组里面的 id 是自定义布局中各个控件的 id,顺序需要与上面的 from 中的顺序对应)

BaseAdapter

继承 BaseAdapter 时,必须重写它的 4 个方法,具体如下:

  • getCount():返回 adapter 中数据的个数,即返回列表项的行数
  • getItem(int position):获得相应数据集合中特定位置的数据项,即返回当前 Item 显示的数据
  • getItemId(int position):返回 Item 的 Id
  • getView(int position, View convertView, ViewGroup parent):每一个 Item 项创建时被调用(即每一次 Item 从屏幕外滑进屏幕内的时候调用,或者程序刚开始的时候创建第一屏 Item 的时候调用)
  • position:界面上 Item 的 Id
  • convertView:展示在界面上的一个 Item,可以用来缓存布局
  • parent:加载 XML 视图时使用

Adapter 和 ViewAdapter 结合使用


Spinner (列表选择框)

Spinner,顾名思义,当需要用户选择的时候,可以提供一个列表将所有可选项列出来,供用户选择。

Spinner 的列表项数据的获取方法有两种,一是直接在 XML 布局文件中为 android:entries 属性指定数组作为数据源,二是在代码中通过 AdapterView 的 setAdapter(adapter) 设置。

1. 在 XML 布局中指定数组作为数据源

  1. 在 values 文件下新建一个 arrays.xml 文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>    
  <string-array name="phone_brand">       
    <item>HTC</item>        
    <item>iPhone</item>      
    <item>Samsung</item>     
    <item>Motorola</item>     
    <item>Huawei</item>    
    <item>Nokia</item>    
  </string-array>
</resources>
  1. 在 XML 布局文件中定义一个 Spinner,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="net.monkeychan.spinnertest.MainActivity" > 
 
  <Spinner     
    android:layout_width="match_parent"    
    android:layout_height="wrap_content"  
    android:entries="@array/phone_brand" />  
</LinearLayout>

注: android:spinnerMode 属性可以设置 Spinner 的样式,当设置为 android:spinnerMode="dropdown" 时,为下拉样式;当设置 android:spinnerMode="dialog" 时,为弹出选择框样式,此时可以添加属性 android:prompt,为弹出的选择框添加标题。

A. 设置为 android:spinnerMode="dropdown",即下拉样式

  • XML 文件布局:

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.monkeychan.spinnertest.MainActivity" >

 <Spinner     
   android:layout_width="match_parent"    
   android:layout_height="wrap_content"  
   android:entries="@array/phone_brand" 
   android:spinnerMode="dropdown" />  

</LinearLayout>


- 效果演示:
![](http://upload-images.jianshu.io/upload_images/1850626-3bc5c82887f05972.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

B. 设置为 android:spinnerMode="dialog",即弹出选择框样式

- XML 文件布局:
- ```
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="net.monkeychan.spinnertest.MainActivity" > 
 
    <Spinner     
       android:layout_width="match_parent"    
       android:layout_height="wrap_content"  
       android:entries="@array/phone_brand" 
       android:spinnerMode="dialog"
       android:prompt="@string/select_phone_brand" />  
</LinearLayout>

上面代码中,android:prompt 属性用于设置弹出选择框的标题。注意,此处只能引用字符串变量,而不能直写标题的内容,否则编译时会出错。

  • 效果演示:


2. 在代码中通过 AdapterView 的 setAdapter(adapter) 设置

  • XML 文件布局:

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.monkeychan.spinnertest.MainActivity" >

<TextView
    android:layout_width="wrap_content"    
    android:layout_height="wrap_content"
    android:text="请选择城市:" />

<Spinner     
    android:id="@+id/spinner"
    android:layout_width="match_parent"    
    android:layout_height="wrap_content" />  

</LinearLayout>


- Java 代码:

public class MainActivity extends AppcompatActivity {

private String[] location = { "北京", "广东", "浙江", "四川", "海南", "福建" };

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 1. 从布局中获取到 Spinner 的实例
    Spinner spinner = (Spinner) findViewById(R.id.spinner);
    
    // 2. 创建一个 ArrayAdapter 的对象,并进行初始化
    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_dropdown_item, location);
    
    // 3. 为 Spinner 设置 Adapter
    spinner.setAdapter(arrayAdapter);

}

}


- 效果演示:
![](http://upload-images.jianshu.io/upload_images/1850626-aaeb4b21cfc48c75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上面的代码中我们使用了 ArrayAdapter,实际上也可以使用其它 Adapter,如 SimpleAdapter、扩展 BaseAdapter 等,道理是一样的。

##GridView 

> 1. GridView,即网格视图,用于在界面上按行、列分布的方式来显示多个组件;
> 2. GridView 默认为一列,如果想要显示多列,需要在 XML 布局中为属性 android:numColumns 或在代码中 使用方法 setNumColumns(int) 指定列数,而行数是动态改变的,无需指定。

**值得注意的是,虽然 GridView 和 ListView 一样继承了 AbsListView,但 GridView 并没有 android:entries 属性,所以我们不能在 XML 布局中为 GridView 指定数据源,只能在代码中通过 AdapterView 的 setAdapter(adapter) 设置。**

下面是我们要达到的效果:
![](http://upload-images.jianshu.io/upload_images/1850626-bb0805dbe83e463f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**注:** 这次我们使用 SimpleAdapter 来实现。

**下面我们以水果为例,图片为水果图片,文字为水果名称**

1) 由于图中有行和列,所以我们可以使用 GridView 来实现,从图中可以看出,总共有 3 列。下面是 XML 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<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"
android:gravity="center_horizontal"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.monkeychan.gridviewtest.MainActivity">

<GridView
    android:id="@+id/gridView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:numColumns="3" />

</LinearLayout>


2) 自定义样式文件,该文件作为列表项的组件,控制列表项的外观:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">

<!-- 自定义一个 ImageView,用来显示图片 -->
<ImageView
    android:id="@+id/fruit_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<!-- 自定义一个 TextView,用来显示文字 -->
<TextView
    android:id="@+id/fruit_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="5dp" />

</LinearLayout>


3) Java 代码:

public class MainActivity extends AppCompatActivity {

// 定义一个 int 型数组,用来存放水果对应图片的资源 id
private int[] images = {R.drawable.apple_pic, R.drawable.banana_pic, R.drawable.cherry_pic,
        R.drawable.grape_pic, R.drawable.mango_pic, R.drawable.orange_pic, R.drawable.pear_pic,
        R.drawable.pineapple_pic, R.drawable.strawberry_pic};

// 定义一个 String 类型的数组,用来存放水果的名称
private String[] names = {"苹果", "香蕉", "樱桃", "葡萄", "芒果", "香橙", "雪梨", "菠萝", "草莓"};

@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 集合,用来存放水果图片和水果名称
        Map<String, Object> listItem = new HashMap<String, Object>();
        listItem.put("images", images[i]);
        listItem.put("names", names[i]);
        listItems.add(listItem);
    }

    // 1. 从布局中获取到 GridView 的实例
    GridView gridView = (GridView) findViewById(R.id.gridView);

    // 2. 创建一个 SimpleAdapter 的实例,并进行初始化
    SimpleAdapter simpleAdapter = new SimpleAdapter(
            this, listItems, R.layout.gridview_item, new String[] {"images", "names", new int[] {R.id.fruit_image, R.id.fruit_name});

    // 3. 为 GridView 设置 Adapter
    gridView.setAdapter(simpleAdapter);
}

}


4) 效果演示:
![](http://upload-images.jianshu.io/upload_images/1850626-656aa33769ebc904.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上面的代码中我们使用了 SimpleAdapter,实际上也可以使用其它 Adapter,如 ArrayAdapter、扩展 BaseAdapter 等,道理是一样的。

##ListView 

> ListView ,以**垂直列表**的形式显示所有列表项。

**与 Spinner 类似,ListView 的列表项数据的获取方法有两种,一是直接在 XML 布局文件中为 android:entries 属性指定数组作为数据源,二是在代码中通过 AdapterView 的 setAdapter(adapter) 设置。**

###1. 在 XML 布局中指定数组作为数据源

1) 在 values 文件下新建一个 arrays.xml 文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="phone_brand">
<item>HTC</item>
<item>iPhone</item>
<item>Samsung</item>
<item>Motorola</item>
<item>Huawei</item>
<item>Nokia</item>
</string-array>
</resources>


2) 在 XML 布局文件中定义一个 ListView,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.monkeychan.listviewtest.MainActivity" >

<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/phone_brand" />
</LinearLayout>


3) 效果演示:
![](http://upload-images.jianshu.io/upload_images/1850626-26b5c3453e919a75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###2. 在代码中通过 AdapterView 的 setAdapter(adapter) 设置

下面是我们要达到的效果:
![](http://upload-images.jianshu.io/upload_images/1850626-1711afd8450d830e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**注:** 这次我们使用自定义 Adapter。

**下面我们仍然以水果为例,图片为水果图片,文字为水果名称**

1) 首先定义我们自己的 Adapter,从图中可以看出,Adapter 中要有文字和图片,所以我们可以用一个 List<String> 类型的集合和 List<Integer> 类型的集合来存放文字和图片(因为在 R.java 文件中图片资源的 id 是 int 类型的)。自定义的 Adapter 如下:

public class MyListViewAdapter extends BaseAdapter {

private Context mContext;
private int mResource;
private List<Integer> mImage;
private List<String> mText;

public MyListViewAdapter(Context context, int resource, List<Integer> image, List<String> text) {
    mContext = context;
    mResource = resource;
    mText = text;
    mImage = image;
}

@Override
public int getCount() {
    return mText.size();
}

@Override
public Object getItem(int position) {
    return mText.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // LayoutInflater,布局加载器,用来加载从外部传进来的布局
    convertView = LayoutInflater.from(mContext).inflate(mResource, null);
    // 注意,外部传进来的布局文件中必须要有 id 为 fruit_image 的 ImageView 和 id 为 fruit_name 的 TextView,
    // 否则会出现 NullPointerException 错误,即空指针
    ImageView iv = (ImageView) convertView.findViewById(R.id.fruit_image);
    TextView tv = (TextView) convertView.findViewById(R.id.fruit_name);
    iv.setImageResource(mImage.get(position));
    tv.setText(mText.get(position));
    return convertView;
}

}


2) XML 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.monkeychan.listviewtest.MainActivity">

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

</LinearLayout>


3) 自定义样式文件,该文件作为列表项的组件,控制列表项的外观:

<?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:id="@+id/fruit_image"
    android:layout_width="36dp"
    android:layout_height="36dp" />

<TextView
    android:id="@+id/fruit_name"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="10dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="16sp"/>

</LinearLayout>


4) Java 代码:

public class MainActivity extends AppCompatActivity {

// 定义一个 int 型数组,用来存放水果图片的 id,图片文件放在 drawable 文件夹下
private int[] images = {R.drawable.apple_pic,
        R.drawable.banana_pic, R.drawable.cherry_pic,
        R.drawable.grape_pic, R.drawable.mango_pic,
        R.drawable.orange_pic, R.drawable.pear_pic,
        R.drawable.pineapple_pic, R.drawable.strawberry_pic,
        R.drawable.watermelon_pic};

// 定义一个String 类型数组,用来存放水果名称
private String[] names = {"苹果", "香蕉", "樱桃", "葡萄", "芒果", "香橙",
        "雪梨", "菠萝", "草莓", "西瓜"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 创建一个 List<Integer> 集合,用来存放水果图片
    List<Integer> imagesList = new ArrayList<>();
    for (int i = 0; i < images.length; i++) {
        imagesList.add(images[i]);
    }

    // 创建一个 List<String> 集合,用来存放水果名称
    List<String> namesList = new ArrayList<>();
    for (int i = 0; i < names.length; i++) {
        namesList.add(names[i]);
    }

    // 1. 从布局中获取到 ListView 的实例
    ListView listView = (ListView) findViewById(R.id.listView);

    // 2. 创建一个 MyListViewAdapter 的对象,并进行初始化
    MyListViewAdapter myListViewAdapter = new MyListViewAdapter(this, R.layout.listview_item, imagesList, namesList);

    // 3. 为 ListView 设置 Adapter
    listView.setAdapter(myListViewAdapter);
}

}


5) 效果演示:
![](http://upload-images.jianshu.io/upload_images/1850626-5cbd0c0cdcbd4eb7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上面的代码中我们使用了自定义 Adapter,实际上也可以使用其它 Adapter,如 ArrayAdapter、扩展 BaseAdapter 等,道理是一样的。

##自定义 Adapter 的优化——提升 AdapterView 的运行效率

以上面的 ListView 的为例,我们自定义了一个 Adapter,来看看我们的 getView() 方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// LayoutInflater,布局加载器,用来加载从外部传进来的布局
convertView = LayoutInflater.from(mContext).inflate(mResource, null);
ImageView iv = (ImageView) convertView.findViewById(R.id.fruit_image);
TextView tv = (TextView) convertView.findViewById(R.id.fruit_name);
iv.setImageResource(mImage.get(position));
tv.setText(mText.get(position));
return convertView;
}


前面我们说过,getView() 方法是每一个 Item 项创建时被调用,并且在 getView() 方法中,我们每次都将布局重新加载了一遍。当我们的 Item 项数目超出屏幕可显示范围时,而我们又来回滑动 ListView 时,其实是多个 Item 项在被反复创建、同一个布局在被反复加载,而每一次创建 Item 项、加载布局时,就会消耗一次系统资源,这对系统来说是极大的开销。当多次滑动过后,有可能造成滑动的过程中出现卡顿,造成的用户体验非常不好。那么,有没有这种可能,将之前已经创建好的 Item 项和已经加载过的布局缓存起来,当再次使用时,只须从缓存中拿出来使用,而不用再次创建呢?这就是下面我们要做的。

1. 首先,我们要对布局进行缓存:
我们可以在调用 getView() 方法时进行判断,如果缓存中不存在布局,我们才去加载布局,否则不加载。getView() 方法中有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便进行重用。至此,布局缓存的问题解决了。但是,在 getView() 方法中,我们每次都会调用 findViewById() 方法来获取控件的实例,这部分还可以优化;

2. 其次,对控件实例进行缓存:
我们可以定义这样一个类,它负责缓存控件的实例,我们给这个类取名叫 ViewHolder,当 convertView 为空(即缓存中不存在布局)时,创建一个 ViewHolder 对象,将控件的实例存储在 ViewHolder 中。

**下面是改写后的自定义 Adapter:**

public class MyListViewAdapter extends BaseAdapter {

private Context mContext;
private int mResource;
private List<Integer> mImage;
private List<String> mText;

public MyListViewAdapter(Context context, int resource, List<Integer> image, List<String> text) {
    mContext = context;
    mResource = resource;
    mText = text;
    mImage = image;
}

@Override
public int getCount() {
    return mText.size();
}

@Override
public Object getItem(int position) {
    return mText.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    // 判断 convertView 是否为空
    if (convertView == null) {
        // LayoutInflater,布局加载器,用来加载从外部传进来的布局
        convertView = LayoutInflater.from(mContext).inflate(mResource, null);
        // 创建 ViewHolder 的对象
        viewHolder = new ViewHolder();
        // 将控件实例存储在 ViewHolder 中
        viewHolder.iv = (ImageView) convertView.findViewById(R.id.fruit_image);
        viewHolder.tv = (TextView) convertView.findViewById(R.id.fruit_name);
        // 将 ViewHolder 存储在 convertView 中,即缓存布局
        convertView.setTag(viewHolder);
    } else {
        // 重新获取 ViewHolder
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.iv.setImageResource(mImage.get(position));
    viewHolder.tv.setText(mText.get(position));
    return convertView;
}

// 创建一个内部类 ViewHolder,用来缓存控件实例
class ViewHolder {
    ImageView iv;
    TextView tv;
}

}


##总结

**AdapterView 和 Adapter 结合使用的步骤:**
1. 从布局中获取到 AdapterView 的实例,即 findViewById();
2. 创建适合的 Adapter 对象,并进行初始化(根据 Adapter 的构造方法的参数列表传入对应的参数类型);
3. 为 AdapterView 设置 Adapter;
4. 当自定义 Adapter 时,应注意优化方面的问题。

----
参考资料:
- [《疯狂 Android 讲义》- 李刚](http://www.crazyit.org)
- [《第一行代码——Android》- 郭霖](http://guolin.tech)
- [Android ArrayAdapter 详解 - 彭香香的专栏](http://blog.csdn.net/nairuohe/article/details/6457300)
- [Android ListView使用BaseAdapter与ListView的优化](http://www.open-open.com/lib/view/open1339485728006.html)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容