看源码之Adapter和AdapterView之间的关系

newtrekWang 2015-02-23

总述

Android中“列表”的实现其实一个典型的MVC模式,其实中AdapterView相当于是View,负责视图的绘制以及视图的事件响应,Adapter相当于是Controller,负责控制数据的显示内容和展现方式,另外项目中的实体类则是代表了Model。

Adapter

Adapter其实是个接口,并不是一个具体的类。它的主要最用就是作为一个AdapterView和Model间的桥梁,这一点在源码中有很清楚的定义:

/**
 * An Adapter object acts as a bridge between an {@link AdapterView} and the
 * underlying data for that view. The Adapter provides access to the data items.
 * The Adapter is also responsible for making a {@link android.view.View} for
 * ... ...
 */

getView()是Adapter非常重要的函数之一,这个函数的主要作用就根据在"列表"中位置的不同而展示不同的数据。具体可详见该方法的源码注释,上面已写的非常清楚了。
另一个就是registerDataSetObserver()和unregisterDataSetObserver(),好吧,应该是一对,这其实就是典型的一个观察者的设计模式,如果Adapter中需要加载的数据发生了变化,则我们就是通知Adapter来更新数据。当然,我们一般在项目中使用的是notifyDataSetChanged()方法,这是因为BaseAdapter不仅继承了Adapter,而且还对其中的一些方法进行封装,这其中就包括了DataSetObservable的notifyChanged()方法,源码如下:

/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */
public void notifyDataSetChanged() {
    mDataSetObservable.notifyChanged();
}

AdapterView

AdapterView也是一个抽象类,例如AbListView等都是继承它而来。AdapterView中主要是一些监听器的设定,如:

Item 长按监听器

public interface OnItemLongClickListener {
    /**
     * Callback method to be invoked when an item in this view has been
     * clicked and held.
     *... ...
     */
    boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id);
}

Item 点击监听器
public interface OnItemClickListener {

/**
     * Callback method to be invoked when an item in this AdapterView has
     * been clicked.
     *... ... 
     */
    void onItemClick(AdapterView<?> parent, View view, int position, long id);
}

还有最常用且基本的等方法,如:

/**
 * Returns the adapter currently associated with this widget.
 *... ...
 */
public abstract T getAdapter();

/**
 * Sets the adapter that provides the data and the views to represent the data
 * in this widget.
 *... ...
 */
public abstract void setAdapter(T adapter);

虽然AdapterView只是一个抽象类,但是其中的"干货"确实不是少,有着许多非常有用但是不常用的方法,如:

public boolean performItemClick(View view, int position, long id) {
    if (mOnItemClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        if (view != null) {
            view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        }
        mOnItemClickListener.onItemClick(this, view, position, id);
        return true;
    }

    return false;
}

顾名思义这是一个可以实现自动点击Item的方法,当你需要时直接使用可以省去不少的功夫。

结语

相关推荐