简析 Android Adapter适配器的内部调用流程

我们都知道使用Adapter为ListView或GridView填充数据,而我们需要实现Adapter里的getView、getCount等方法。但内部到底是怎么调用,怎么调用的getView方法,就需要看源码了,下面来简单分析一下:

以GridView为例,为它设置适配器的方法是GridView.setAdapter:

@Override
    public void setAdapter(ListAdapter adapter) {
        。。。。。。
        mDataSetObserver = new AdapterDataSetObserver();
        mAdapter.registerDataSetObserver(mDataSetObserver);
        。。。。。。
        requestLayout();//调用了requestLayout重绘布局方法,简称 重绘(1)。
    }
方法中为adapter注册了一个监听器AdapterDataSetObserver,它存在于GridView的父类AbsListView中(其实这个监听器的真正实现是在AdapterView类中),这个监听器有一个主要的监听方法:
public void onChanged() {
            mDataChanged = true;
            mOldItemCount = mItemCount;
            mItemCount = getAdapter().getCount();

            // Detect the case where a cursor that was previously invalidated has
            // been repopulated with new data.
            if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
                    && mOldItemCount == 0 && mItemCount > 0) {
                AdapterView.this.onRestoreInstanceState(mInstanceState);
                mInstanceState = null;
            } else {
                rememberSyncState();
            }
            checkFocus();
            requestLayout();//注意这里也调用了重绘布局方法,简称 重绘(2)
        }
requestLayout会向系统发一个重新布局的message,重新布局就要重新测量,就要走measure流程,最终会调用到GridView中的onMeasure方法(具体过程可查看android内核剖析的第十三章关于View的绘制内容)。而在GridView的onMeasure中就会调用为GridView设置的Adapter对象的getCount、getItemType方法还会调用一个obtainView(存在于GridView的父类AbsListView中),obtainView中会就会调用Adapter的getView方法来获得单个Item的View了。
 
  

了解了这些之后,就可以清楚的了解适配器的调用流程了:

场景1:我们在为GridView设置Adapter(GridView.setAdapter)时最终会调用 “重绘(1)”,然后就会一直调用到GridView的onMeasure方法,在onMeasure方法里就会调用Adapter的getcount、getView等方法获取数据了。

场景2:当数据源改变,我们会调用adapter的notifyDataSetChanged方法来刷新数据,这样会触发Adapter中注册的监听器,最终会调用“重绘(2)”,之后就同场景1的过程一样来获取adapter的数据了。




你可能感兴趣的:(android)