Android Adapter 源码笔记(2)

  1. ArrayAdapter,很直白的懒人适用型Adapter, 不过要求对应的Data可以以数组的形式表示. 也算是个半教学演示,在构造的时候就会要求一个layout的resoource id,该layout表示的就是ListView中每个View的布局,并且考虑到常规的应用场景都会每个View显示出Data的内容,还可以选择性的给一个layout中的TextView的resId,这样ArrayAdapter会自动的为其设置内容.
    • 内部一个List mObjects,就是Data的具现化.
    • Object mLock = new Object(),一个锁,用来作为Data修改的锁,除此之外,在filter的时候也会被使用到(这就是为什么不干脆使用一个同步List的一部分原因).
    • mResource/mDropDownResource,对应的List/Spinner中的每个Item的View的layout.
    • mFieldId, layout中的TextView的resId.
    • mNotifyOnChange,在Data变化的时候是否会notifyDataSetChanged()(默认为true).
    • ArrayList mOriginalValues/ArrayFilter mFilter:
    • ArrayAdapter的构造函数好几套,context和view的layout resourse是必须的,同时还可以接受,textViewResId,List objects(初始化时就指定了data),T[]也可以作为Data接受.构造中调用的init函数很简单,保存传入的引用/根据传入的生成.
    • getCount(), 数组的长度.
    • T getItem(int position), 返回数组在位置pos的成员.
    • getPosition(T item), 数组的indexOf
    • getItemId(int position), ArrayAdapter默认了data的ItemId与相应的View的pos是相等的,因此这里直接原样返回pos.
    • getView(…)->createViewFromResource(…):如果convertView是null,那么直接根据layout res inflate一个View.如果mField 为 0(构造时没有指定),那么直接假设整个View是一个TextView,否则在layout中查找一个mField对应的View并转TextView,如果ClassCast失败,那么抛出一个IllegalStateException,ArrayAdapter强制View必须是或者必须有TextView(并且构造时指定).在的到了TextView以后,就会根据data的内容item来setText,如果data指定pos的对象本身就是CharSequence的话,那么直接setText,否则setText的内容是item.toString.从这里可以看出,ArrayAdapter是方便,但是也已经把所有的都做了,基本没有可定制的地方,不过人家本身就是一个具体派生了,无可厚非,嫌不自由用BaseAdapter去
    • 还蛋疼的提供了一个staic的createFromResource(…),用来根据输入参数生成一个ArrayAdapter,也是为了懒人,连T都不用自己标了.
    • 附赠了一个ArrayFilter类,可以按照prefix进行过滤. mOriginalValues就是在filter的过程中作为一个多线程安全的swap使用的,在要进行filter时(performFiltering(CharSequence prefix)),会将mObjects的引用全部 copy给mOriginalValues(加锁),后面的操作还会将mOriginalValues重新copy到一个本地的values数组中,后面的一系列过滤都是针对此value(不过只在copy加锁了,而没有在后面的filter过程中加锁,这可能会造成filter过程中,对mObjects/mOriginalValues的修改无效化,可能是AdpaterView派生类做了这方面的保证?) Filter的publishResults(…)(过滤完的callback)会将result设给mObjects,如果result还有data,那么notifyDataSetChanged().否则 notifyDataSetInvalidated()(总算见到了这个函数的用武之地, Invalidated在这里代表的意思就是数据已经无效,但是呢,和empty还有点区别吧,否则犯不着专门一个函数).
    • sort(Comparator<? super T> comparator): 可以自己定制一个cmp, 并且在s对mObjects进行sort(会加锁)以后会根据mNotifyOnChange来notifyDataSetChanged()(一般来说会触发相应AdapterView具体类的UI刷新).
    • add/addAll/insert/remove/clear基本同上不赘述.
    • 上面对Data的修改函数,在mOriginalValues这个多线程安全swap存在时,修改会作用到mOriginalValues上.

你可能感兴趣的:(android)