首页 > 代码库 > Android笔记十一.ListView+Adapter

Android笔记十一.ListView+Adapter

深入理解Adapter
一、ListView
    ListView是Android开发过程中较为常见的组件之一,它将数据以列表的形式展现出来。一般而言,一个ListView由以下三个元素组成:
1.View展示列表视图,通常是一个xml所指定的大家都知道Android的界面基本上是由xml文件负责完成的,所以ListView的界面也理所应当的使用了xml定义。例如在ListView中经常用到的“android.R.layout.simple_list_item_1”等, 就是Android系统内部定义好的一个xml文件。
2.Adapter适配器:用于将不同的数据映射到View上。不同的数据对应不同的适配器,如ArrayAdapter,CursorAdapter, SimpleAdapter等, 他们能够将数组指针指向的数据Map等数据或基本组件映射到View上。也正是由于适配器的存在,使得ListView的使用相当灵活,经过适配器的处理后,在 view看来所有的数据映射过来都是一样的。
3.数据:具体的数据和资源。可以是字符串图片、Map映射等,通过适配器这些数据将会被现实到 ListView上。
    总之,所有的数据和资源要显示到ListView上都通过适配器来完成。ArrayAdapter,CursorAdapter, SimpleAdapter为系统已有的适配器,可以将如数组、Cursor指向的数据(一般为数据库)、Map里的数据。

二、深入理解Adapter
1.概要:Adapter是连接后端数据和前端视图显示的适配器接口,是数据和UI(View)之间的桥梁。通过适配器,可以将不同的数据映射并显示到View上。在常见的View(ListView、GridView)等地方都需要用到Adapter。对于Data、Adapter、View的关系,如下图所示:
技术分享
2.Android中Adapter类
(1)BaseAdapter适配器为一个抽象类,使用该类可以实现更为复杂的ListView。通过文档可以看出,ArrayAdapter,CursorAdapter, SimpleAdapter都继承于BaseAdapter。所以通过继承BaseAdapter就可以完成自己的Adapter,可以将任何复杂组合的数据和资源,以任何你想要的显示效果展示处理。继承BaseAdapter之后,需要重写以下四个方法:getCount,getItem,getItemId,getView。但是,ArrayAdapter,CursorAdapter, SimpleAdapter则无须要全部重写上述四种方法。
(2)ArrayAdapter适配器支持泛型操作,最为简单,只能展示一行字符串
(3)SimpleAdapter适配器有最好的扩充性,可以自定义出各种效果(字符串、图片、Map集),通常使用xml布局文件来指定视图。
(4)SimpleCursorAdapter适配器可以适用于简单的纯文字型ListView,它需要Cursor的字段和UI的id对应起来。如需要实现更复杂的UI也可以重写其他方法。可以认为是SimpleAdapter对数据库的简单结合,可以方便地把数据库的内容以列表的形式展示出来。
技术分享
技术分享
3.ListView加载adapter一般过程
(1)先判断adapter有多少数据项,根据这个数据确定有多少item(列表项). -----getCount()方法实现 
(2)确定每个item里加载哪个View.                                     -----getView()方法实现
(3)向对应的View中加载需要显示的数据
4.ArrayAdapter实例分析
(1)开发基本思路
    ArrayAdapter适配器支持泛型操作,列表的每一项只能显示一串字符,不能显示图片等资源数据。
*使用字符串数组作为数据源
a.实现一个字符串数组作为数据源(List集)(数组元素有几个,就有几个列表项)
b.实例化一个ArrayAdapter<String> 适配器对象,用于装配数据源到指定的View.
ArrayAdapter<String> adapter=new ArrayAdapter<String>( this,android.R.layout.simple_expandable_list_item_1, strs); 
c.将ArrayAdapter适用于ListActivity的ListView
setListAdapter(adapter);
*使用List集合(ArrayList)作为数据源
a.实例化一个ListView对象
b.实例化一个ArrayAdapter<String>对象(集合中数据项类型为String),将Map集合中的数据项映射到列表项中;
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData()); 
c.装配Adapter到ListView中并显示ListView视图
listview.setAdapter(adapter); //装配Adapter到ListView
setContentView(listview); //将list视图显示
(2)源代码分析一
MainActivt.java
package com.example.android_arraylist_1;
mport android.app.ListActivity; 
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class MainActivity extends ListActivity
{
     public void onCreate(Bundle savedInstanceState){
      super.onCreate(savedInstanceState);
      String[] strs={"第一项","第二项","第三项","第四项"}; //列表项数据
      ArrayAdapter<String> adapter=new ArrayAdapter<String>(  //实例化一个ArrayAdapter适配器来装配数据
            this, //上下文
            android.R.layout.simple_expandable_list_item_1, //列表的每一行布局,只显示一行文字
            strs); //数据源(一个List集合)
  setListAdapter(adapter); //将List集合数据显示在List视图中
 }
}
分析:
    上面代码使用了ArrayAdapter(Context context, int textViewResourceId, List<T> objects)来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()完成适配的最后工作。
效果:
技术分享技术分享
    
(3)源码分析二
ArrayListActivity.java
package com.example.android_arraylist_2;
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 ArrayListActivity extends Activity {
 private ListView listview; //定义一个ListView对象
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  listview =new ListView(this); //实例化一个ListView对象
  ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, //实例化一个适配器adapter
         android.R.layout.simple_expandable_list_item_1, //布局文件:显示一行文字
         getData()); //获取数据源(ArrayList集合)
  listview.setAdapter(adapter); //装配Adapter到ListView
  setContentView(listview); //将list视图显示
 
 }
 private List<String> getData() {
  // TODO Auto-generated method stub
  List<String> data=http://www.mamicode.com/new ArrayList(); //实例化一个ArrayList集合,用于装载数据
  data.add("测试数据1"); //向ArrayList集合中添加元素数据
  data.add("测试数据2");
  data.add("测试数据3");
  data.add("测试数据4");
  return data; //返回ArrayList集合对象
 }
}
分析:
(1) getData()
(2) List<String> 
(3) List<String> data=http://www.mamicode.com/new ArrayList()
效果:
技术分享技术分享

5.SimpleAdapter实例分析
   与ArrayAdapter不同的是,simpleAdapter的扩展性最好,可以定义各种各样的布局出来,可以放上ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。一般情况下,我们都是利用Map哈希表作为数据源,通过键到组件Id的映射实现列表项内容
(1)开发基本思路
a.装配适配器,将Map键数据资源映射到Id所对应的组件上;
 SimpleAdapter adapter =new SimpleAdapter(this, //上下文
            getData(), //获取list数据集
            R.layout.simple, //指定布局文件
            new String[]{"img","title1","info"}, //Map集合键
            new int[]{R.id.img,R.id.title1,R.id.info});//界面组件Id
b.实现一个Map集合,并将map对象添加ArrayList
 List<Map<String,Object>> list=new ArrayList<Map<String,Object>>(); //实例化一个ArrayList对象,
 Map<String,Object> map=new HashMap<String,Object>(); //设置列表第一项标题与图标(使用Map)
c.ArrayAdapter适用于ListActivity的ListView
 setListAdapter(adapter);
(2)源代码分析
SimpleAdapterActivity.java
package com.example.android_sampleadapter_1;
import java.util.ArrayList; 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ListActivity; 
import android.os.Bundle;
import android.widget.SimpleAdapter;
public class SimpleAdapterActivity extends ListActivity { 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
 //1.装配适配器,并绑定数据到相应的视图
  SimpleAdapter adapter =new SimpleAdapter(this, //上下文
            getData(), //获取list数据集
            R.layout.simple, //指定布局文件
            new String[]{"img","title1","info"}, //Map集合键
            new int[]{R.id.img,R.id.title1,R.id.info});//界面组件Id
 //2.显示视图
  setListAdapter(adapter);
 }
 //3.Map数据集:HashMap构成的List,list的每一节对应ListView的每一行
  //HashMap的每个键值数据映射到布局文件中对应id的组件上
 private List<Map<String,Object>> getData() {
  // TODO Auto-generated method stub
  List<Map<String,Object>> list=new ArrayList<Map<String,Object>>(); //实例化一个ArrayList对象,
  Map<String,Object> map=new HashMap<String,Object>(); //设置列表第一项标题与图标(使用Map)
  map.put("img", R.drawable.a);
  map.put("title1", "华为荣耀");
  map.put("info", "学人家玩抢购,真TM坑爹!");
  list.add(map); //将一个map对象添加到列表中
 
  map=new HashMap<String,Object>();
  map.put("img", R.drawable.b);
  map.put("title1", "中国移动");
  map.put("info", "god knows");
  list.add(map); //将一个map对象添加到列表中
 
  map=new HashMap<String,Object>();
  map.put("img", R.drawable.c);
  map.put("title1", "中兴");
  map.put("info", "手机还不错,只是要死不活的");
  list.add(map); //将一个map对象添加到列表中
 
  map=new HashMap<String,Object>();
  map.put("img", R.drawable.d);
  map.put("title1", "魅族4");
  map.put("info", "有点贵!");
  list.add(map); //将一个map对象添加到列表中
 
  return list;
 }
分析:
    使用simpleAdapter的数据用一般都是HashMap构成的Listlist的每一节对应ListView的每一行HashMap的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局simple.xml。下面做适配,new一个SimpleAdapter参数一次是:this,布局文件(vlist.xml),HashMap的 title 和 info,img,布局文件的组件id,title,info,img。布局文件的各组件分别映射到HashMap的各元素上,完成适配。
simple.xml-列表项布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:orientation="horizontal" 
android:layout_width="match_parent" 
android:layout_height="match_parent" > 

<ImageView 
android:id="@+id/img" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_margin="10dp"/> 
<LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> 
<TextView 
android:id="@+id/title1" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:textColor="#FF000000" android:textSize="22sp"/> 
<TextView 
android:id="@+id/info" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:textColor="#FF000000" android:textSize="13sp"/> 
</LinearLayout> 
</LinearLayout> 
技术分享
6.SimpleAdapter实例分析
package com.example.android_simplecuroradapter;
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListAdapter;
public class SimpleCursorActivity extends ListActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  //1.获得一个指向系统通讯录数据库的CurSor对象获得数据来源
  Cursor cur=getContentResolver().query(People.CONTENT_URI, null, null, null, null);
  startManagingCursor(cur);
  //2.实例化列表适配器
  ListAdapter adapter=new SimpleCursorAdapter(this,android.R.layout.simple_expandable_list_item_1,cur,new String[] {People.NAME},new int[] {android.R.id.text1});
  //3.显示视图
  setListAdapter(adapter);
 }
}
分析:
    一定要以数据库作为数据源的时候,才能使用SimpleCursorAdapter,这里特别需要注意的一点是:不要忘了在AndroidManifest.xml文件中加入权限
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
效果:
技术分享
技术分享
参考:
1.http://www.cnblogs.com/Gaojiecai/archive/2012/10/08/2715962.html
2.http://wenku.baidu.com/link?url=1ln6lAvzN9E-1eOuEfy2E_i1O0Ws8gE0KcySX-yu-j7wEzgd1EkuDhwcfeCcM48egMIFb-Egm7mh1RODs9hkXw8C1zjqNkIa4lyvH5oliHO
3.http://wenku.baidu.com/view/0224ead8ad51f01dc281f141.html



Android笔记十一.ListView+Adapter