Android Adapter机制 源码笔记(4): AdapterView

  1. abstract class AdapterView extends ViewGroup: 注释已经将其定位解释的很好了:

    An AdapterView is a view whose children are determined by an link Adapter.
    AdapterView的家族还是挺庞大的, 除了Android自带的ListView/GridView/Spinner/…..这些,很多著名的自定义控件也是基于AdapterView的.

  2. ITEM_VIEW_TYPE_IGNORE = -1:这个type的作用是Adapter**不想某个Item的View被recycle的话**,其getItemViewType()就会返回这个值.

  3. ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2: 对应的View是header/footerView时, getItemViewType()会返回这个值

  4. mInLayout: 标示AdapterView是被layout过了.

  5. mDataChanged: 用来标示AdapterView所bind的data,自上次layout至今是否又产生过变化. mOldItemCount则用来标示data change前adapter中item的数量.

  6. mEmptyView: 就是setEmptyView时的emptyView,注意, emptyView本身并不在AdapterView中.

  7. mBlockLayoutRequests: 当开启这个flag时, 任何对requestLayout()的调用都不会向上传递到父类的View架构中, 这个flag在 一次layout pass的过程中,layout children的时候会被用到.

  8. OnItemClickListener:用的很普遍了, onItemClick(……, View view, int position, long id), 这个回调一般position和id是相等的,不过就像之前说Adapter时,这个完全是自由的,由AdapterView的实现来定制的.

  9. performItemClick(View view, int position, long id),和View的performClick一个道理,等于是模拟一次对ItemView的点击. 如果set了mOnItemClickListener,返回true,否则false.

  10. addView(…)/removeView(….)/这些函数在AdapterView是禁止使用的, 其实现就是直接抛异常: UnsupportedOperationException.这与AdapterView的设计理念有关,因为AdapterView的childView都是由Adapter提供给的,不能有除了Adapter之外的手段来修改childView.

  11. onLayout(…): mLayoutHeight = getHeight(),AdapterView只做了很简单的事情,具体的child layout交予子类来自由实现.

  12. getPositionForView(View view),取得view在Adapter的Dataset中的posititon, 注意view必须是可见的view(不可见的View当前其实没有被在AdapterView中,也就无从查询), 还有一点这里的view可以是ItemView的child, 在实现中可以看到,会先一路向上取到包裹该view的ItemView(当然了,如果本身就是ItemView就不会变了),然后getChildAt(i)挨个做equals匹配(其实应该直接地址匹配就可以). 找不到的话,返回INVALID_POSITION(-1).

  13. getFirstVisiblePosition()/getLastVisiblePosition():返回第一个/最后一个可见的ItemView在DataSet中的position: mFirstPosition/mFirstPosition + getChildCount() - 1,按照AdapterView的设计,第一个可见的ItemView应该就是AdapterView的第一个ChildView,最后一个可见的View就是最后一个childView.

  14. setEmptyView: 同时也是一个RemoteView支持的方法, 在set时就会做一次check,如果adapter==null||adapter.isEmpty(),就会将emptyView显现(updateEmptyStatus).

  15. updateEmptyStatus(empty):紧接上边,会先做一个isInFilterMode(),如果是在filterMode,那么是不会显示emptyView的(相反,会将AdapterView->VISIBLE && emptyView->GONE),否则, 如果emptyView设置了并且有效,那么就会将AdapterView->GONE&&emptyView->VISIBLE,从这个逻辑就可以看到emptyView的使用局限了,其实emptyView就是AdapterView外的一个独立View, 两者的关系仅仅是在empty的时候,AdapterView->GONE&&emptyView->VISIBLE,一个case:如果emptyView本身在布局上不能覆盖AdapterView的位置的话,那么emptyView此时起不到emptyView的效果,最直接的说,emptyView其实就是把我们常用的用view遮挡另一个view方法固化到了AdapterView中((这也是用GONE原因,避免在在LinearLayout这种case,INVISIBLE会造成空白)),没什么复杂的

  16. isInFilterMode():返回false, filter一般在用户在keyboard上输入时可以考虑开启(就是随着根据输入自动过滤AdapterView呈现的itemView).

  17. setFocusable(boolean focusable)/setFocusableInTouchMode(boolean focusable): 从实现上看,只有在!empty或者在filterMode下,才能真正的设置为focusable

  18. getItemAtPosition(int position)/getItemIdAtPosition(int position):很简单,都直接调用的是adapter的相应方法,这也是应该的,因为这个功能完全是依赖于Adapter,当然了,你想在这AdapterView这层玩花样也没人管.

  19. setOnClickListener(OnClickListener l):因为有setOnItemClickListener,所以这个方法是被禁止的.

  20. AdapterDataSetObserver extends DataSetObserver:AdapterView本身没有使用,子类使用,两个callback:

    • onChanged: data发生变化,
      • mDataChanged=true;
      • mOldItemCount = mItemCount;
      • mItemCount = getAdapter().getCount();
      • 一个对cursor case的特殊处理
      • checkFocus()&&requestLayout(),这样才会刷新UI
    • onInvalidated: data无效化(注意和change的区别,change可以是从N变为0,但是变为0和data无效化是不一样的case),
      • mDataChanged = true;
      • 一个对cursor case的特殊处理
      • mOldItemCount/mItemCount/mSelectedPosition等内部标示变量全部INVALID或者置0.
      • checkFocus()&&requestLayout(),这样才会刷新UI
    • AdapterDataSetObserver内部还有一个Parcelable mInstanceState,会在上面两个函数中涉及到AdapterView的onRestoreInstanceState(mInstanceState)/onSaveInstanceState(). clearSavedState()会将mInstanceState null.
  21. canAnimate(): super.canAnimate() && mItemCount > 0.

  22. AdapterView的selection不部分先不详述.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值