Android——Adapter

  1. 基本概念    Adapter(适配器),将一个类的接口变换成客户端所期待的一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。显然Adapter的存在就是为了配合两个不同部分之间的互相协作,使之能够协调工作。在Android中,Adapter是前台UI与底层数据之间联系的纽带,它们之间的关系可表示如下图。
  2. 常用Adapter    Adapter本身只是一个接口,它派生了ListAdapter和SpinnerAdapter两个子接口,其中ListAdapter为AbsListView提供列表项,而SpinnerAdapter为AbsSpinner提供列表项。Adapter接口及其实现类的继承关系如下图所示。

    其中,BaseAdapter、ArrayAdapter、SimpleAdapter、SimpleCursorAdapter这几个是比较常用的Adapter。从上图中可以,看出BaseAdapter是比较重要的,在整个继承关系中处于比较关键的位置。Adapter常用的实现类简介如下:

ArrayAdapter<T>

任意类型(T)数组适配器

BaseAdapter

实现了公共基类Adapter,因此适用于ListView(通过实现指定的ListAdapter接口)和Spinner(通过实现指定的SpinnerAdapter接口)

CursorAdapter

将Cursor中的数据暴露给ListView控件

HeaderViewListAdapter

适用于有ListView Header的ListView控件

ListAdapter

扩展了Adapter,是ListViewts_列表数据之间的桥梁

ResourceCursorAdapter

创建在XML文件中定义的views

SimpleAdapter

将静态数据映射到XML文件定义的view中,功能非常强大

SimpleCursorAdapter

将cursor中的列映射到XML文件定义的TextView或ImageView中

SpinnerAdapter

扩展了Adapter,是Spinnerts_数据之间的桥梁

WrapperListAdapter

包含另外一个列表Adapter的列表Adapter

  1. 使用举例

使用ArrayAdapter创建ListView

这是基本的方法,直接在XML界面中创建ListView,然后在对应的Activity类中进行Adapter绑定即可。注意,AdapterDemo继承自Activity

效果如下:

Android开发中Adapter的作用 安卓开发adapter_Android

Java文件如下所示:

package com.example.adapterdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class AdapterDemo extends Activity
{    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_adapterdemo);
        String[] data= {"北京","上海","广州","西安","南京","深圳","杭州"};
        
        ListView myLV = (ListView)findViewById(R.id.myListView);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.mylv_item,data);
        
        myLV.setAdapter(adapter);
    }
}

Item布局如下,为一个简单的TextView,用于定制每个Item的布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:id="@+id/mylv_item"
    android:textSize="18sp"
    android:layout_width="match_parent"
    android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">
</TextView>

主界面布局如下:

<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"
    tools:context="${relativePackage}.${activityClass}" >
    <ListView
        android:id="@+id/myListView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

使用ListActivity实现列表

    这个方式继承的是ListActivity类,而不是Activity类。ListActivity类默认显示一个列表来展示数据,而且提供Item被点击时的可进行相关操作的方法。

    ListActivity的子类无须调用setContentView()方法来显示某个界面,而是可以直接传入一个内容Adapter,ListActivity的子类就可以呈现出一个列表。

ListActivity持有一个ListView对象,ListActivity无须界面布局文件——相当于它的布局文件中只有一个ListView,因此只要为ListActivity设置Adapter即可。当然用户可以自己定制一个布局,然后在onCreate()方法中通过setContentView(int layoutId)方法来设置用户的自定义布局。需要指出的是,由开发者指定界面布局文件中应该包含一个id为"@+id/android:list"(如果使用代码形式,则是android.R.id.lsit)的ListView。

    效果如下:

Android开发中Adapter的作用 安卓开发adapter_xml_02

    Java类文件如下,此例不需要布局文件,即Xml文件里可以什么没有,或者直接不需要XML布局文件。直接一个java文件就可以了。

package com.example.listactivitydemo;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class ListActivityDemo extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_ts_list); //不需要布局文件,如果需要定制布局文件,则需要按上述说明,按规定指定@+id/android:list,上述详见说明
        
        String [] str = {"HeFie","BeiJing"};         
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,str);
        setListAdapter(adapter);        
    }
}

 

使用SimpleAdapter创建ListView

    SimpleAdapter的功能不简单,相反它具有非常强大的功能,利用它,我们可以定制ListView的外观,或者更复杂的ListView列表项,ListView的大部分场景都可以使用SimpleAdapter。

    效果如下:

Android开发中Adapter的作用 安卓开发adapter_android_03

    Java类文件

package com.example.simpleadapter_demo;

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

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class SimpleAdapter_Demo extends Activity {
    
    private String[] nameStrings = new String[]{"小红","小明","小华"};
    private String[] descsStrings = new String[]{"红红","明明","华华",};
    private int[] imageIds = new int[]{R.drawable.libai,R.drawable.nongyu,R.drawable.qingzhao,R.drawable.tiger};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_adapter__demo);
        
        List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
        for(int i=0; i<nameStrings.length; i++)
        {
            Map<String, Object> listItem = new HashMap<String, Object>();
            listItem.put("header", imageIds[i]);
            listItem.put("personName", nameStrings[i]);
            listItem.put("decs", descsStrings[i]);
            listItems.add(listItem);
        }
        
        SimpleAdapter simpleAdapter = new SimpleAdapter(this,
                listItems, 
                R.layout.simple_item, 
                new String[] {"personName","header","decs"}, 
                new int[]{R.id.name,R.id.header,R.id.desc});
        
        ListView mylistview = (ListView)findViewById(R.id.mylistview);
        mylistview.setAdapter(simpleAdapter);        
    }
}

    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>

    XML主界面布局只有一个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"
    tools:context="${relativePackage}.${activityClass}" >
    
    <ListView
        android:id="@+id/mylistview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        />
</RelativeLayout>

使用BaseAdapter实现ListView

    使用BaseAdapter可以取得对Adapter最大的控制权,程序要创建多少列表项,每个列表项的组件都由开发者来决定。

效果如下:

Android开发中Adapter的作用 安卓开发adapter_ide_04

Java类文件:

 

package com.example.baseadapter;

import java.util.List;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
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 BaseAdapter_Demo extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_adapter__demo);
        
        ListView myList = (ListView) findViewById(R.id.myList);
        BaseAdapter adapter = new BaseAdapter()
        {
            @Override
            public int getCount()
            {
                // 指定一共包含40个选项
                return 40;
            }
            @Override
            public Object getItem(int position)
            {
                return null;
            }
            // 重写该方法,该方法的返回值将作为列表项的ID
            @Override
            public long getItemId(int position)
            {
                return position;
            }
            // 重写该方法,该方法返回的View将作为列表框
            @Override
            public View getView(int position
                    , View convertView , ViewGroup parent)
            {
                // 创建一个LinearLayout,并向其中添加2个组件
                LinearLayout line = new LinearLayout(BaseAdapter_Demo.this);
                line.setOrientation(0);
                ImageView image = new ImageView(BaseAdapter_Demo.this);
                image.setImageResource(R.drawable.ic_launcher);
                TextView text = new TextView(BaseAdapter_Demo.this);
                text.setText("第" + (position +1 ) + "个列表项");
                text.setTextSize(20);
                text.setTextColor(Color.RED);
                line.addView(image);
                line.addView(text);
                // 返回LinearLayout实例
                return line;
            }
        };
        myList.setAdapter(adapter);
        
    }
}

 

XML布局文件如下:

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