Adapter在Android中占据一个重要的角色,它是数据和UI(View)之间一个重要的纽带。android
在常见的View(ListView,GridView)等地方都须要用到Adapter。如图1直观的表达了Data、Adapter、View三者的关系。数据库
图1 Adapter、数据、UI三者关系(PS:此图来自Google I/O)数组
Android中Adapterapp
图2:Android中Adapter类型层级图函数
adapter如同其自己含义,其实就是一个适配器,他能够对要显示的数据进行统一的封装,主要是将数据变成view提供给list。ui
咱们先来看看adapter的体系:spa
public interface Adapter----0层(表示继承体系中的层次)对象
public interface ExpandableListAdapter---(无所谓层次由于没有其余接口继承实现它)继承
这是adapter的始祖,其余个性化的adapter均实现它并加入本身的接口。接口
public interface ListAdapter----1层
public interface SpinnerAdapter----1层
public interface WrapperListAdapter----2层(实现ListAdapter)
以上接口层面上的体系已经完了。
能够看出来做为widget view的桥梁adapter其实只分为2种:ListAdapter和SpinnerAdapter以及ExpandableListAdapter。也就是说全部widget也就是基于list和spinne与ExpandableList三种view形式的。
因为在实际使用时,咱们须要将数据加入到Adapter,而以接口形式呈现的adapter没法保存数据,因而Adapter就转型为类的模式。
public abstract class BaseAdapter----2层(实现了ListAdapter和SpinnerAdapter)
以抽象类的形式出现构造了类型态下的顶层抽象,包容了List和Spinner
public class ArrayAdapter----3层
public class SimpleAdapter---3层
public class CursorAdapter----3层(CursorAdapter其后还有子类这里先不探讨)
基本体系有了以后,让咱们看看顶层Adapter里有哪些方法(只列举经常使用的):
abstract Object getItem(int position)
abstract int getCount()
abstract long getItemId(int position)
abstract int getItemViewType(int position)
abstract View getView(int position,View convertVeiw,ViewGroup parent)
以上是比较重要的方法,ArrayAdapter他们也是从新实现以上方法的。在实际的开发过程当中,每每咱们要本身作属于本身的Adapter,以上方法都是须要从新实现的。
由图2咱们能够看到在Android中与Adapter有关的全部接口、类的完整层级图。在咱们使用过程当中能够根据本身的需求实现接口或者继承类进行必定的扩展。
比较经常使用的有BaseAdapter,ArrayAdapter,SimpleCursorAdapter等。
· BaseAdapter是一个抽象类,继承它须要实现较多的方法,因此也就具备较高的灵活性;
· ArrayAdapter支持泛型操做,一般须要实现getView方法,特殊状况下(结合数据row id),为了让ui事件相应处理方便点最好重写getItemId;
· SimpleCursorAdapter能够适用于简单的纯文字型ListView,它须要Cursor的字段和UI的id对应起来。如须要实现更复杂的UI也能够重写其余方法。
· 若你的数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于经过查询数据库得到Cursor那就使用SimpleCursorAdapter等。
下面分别讲一下它的几个常见的子类:
ListAdapter接口:继承于Adapter。ListAdapter是一个ListView和list上的数据之间的桥梁。数据常常来自于一个Cursor,但这不是必须的。ListView能显示任何数据,只要它是被一个ListAdapter包装的。
BaseAdapter抽象类:是一个实现了既能在ListView(实现了ListAdapter接口)和Spinner(实现了Spinner 接口)里用的Adapter类的通常基类。
ArrayAdapter类:一个管理这样的ListView的ListAdapter:这个ListView被一个数组所支持。这个数组可装任意对象。默认状态下,这个类预期能这样:提供的资源id与一个单独的TextView相关联。若是你想用一个更复杂的layout,就要用包含了域id的构造函数。这个域id可以与一个在更大的layout资源里的TextView相关联。它将被在数组里的每一个对象的toString()方法所填满。你能够添加一般对象的lists或arrays。重写你对象的toString()方法来决定list里哪个写有数据的text将被显示。若是想用一些其它的不一样于TextView的view来显示数组(好比ImageViews),或想有一些除了toString()返回值所填在views里的之外的数据,你就要重写getView(int,View,ViewGroup)方法来返回你想要的View类型。
getView 方法的做用是获得一个View,这个view显示数据项里指定位置的数据,你能够或者手动建立一个view或者从一个XML layout中inflate。当这个view被inflated,它的父view(如GridView,ListView等)将要使用默认的layout参数,除非你用inflate(int,android.view.ViewGroup,boolean)方法来指定一个根view并防止附着在根上。
SimpleAdapter类:一个使静态数据和在XML中定义的Views对应起来的简单adapter。你能够把list上的数据指定为一个Map范型的ArrayList。ArrayList里的每个条目对应于list里的一行。Maps包含着每一行的数据。你先要指定一个XML,这个XML定义了用于显示一行的view。你还要指定一个对应关系,这个对应关系是从Map的keys对应到指定的views。
绑定数据到views发生在两个阶段:若是一个simpleAdapter.ViewBinder是可用的,那么SetViewValue(android.view.View,Object,String)要被调用。若是返回true,那么绑定发生了。若是返回false,那么以下views将被按顺序地尝试:
~实现了Checkable的View(如CheckBox),预期的绑定值是boolen
~TextView,预期的绑定值是String,而且SetViewText方法被调用
~ImageView,预期的绑定值是一个资源的id或String。而且SetViewImage方法被调用
若是没有合适的绑定被发现,一个IllegalStateException被抛出。