0
点赞
收藏
分享

微信扫一扫

Android Adapter机制 源码笔记(5): AbsListView(1)

at小涛 2023-05-23 阅读 68


  1. abstract class AbsListView extends AdapterView implements ……..: 注意,AbsListView里的”List”指的是这个View的data set形式是list(有点不准确),而非这个View真的是一个ListView的形式, 其呈现形式也是完全自定的(layoutChildren()由子类来确定自己的layout方式)里说的很清楚了.

Base class that can be used to implement virtualized lists of items. A list does not have a spatial definition here. For instance, subclases of this class can display the content of the list in a grid, in a carousel, as stack, etc.

  1. mOwnerThread: 保存的是创建了该Thread的thread引用. 后面会有isOwnerThread()用这个做check.
  2. TranscriptMode, (set/getTranscriptMode,不是很明白为什么起transcipt这个名字) 三个选项:
  • TRANSCRIPT_MODE_DISABLED = 0, disable.
  • TRANSCRIPT_MODE_NORMAL = 1: 在最后一个itemView已经可见,并且这时候data又产生了变化,那么在刷新之后会自动scroll到bottom.
  • TRANSCRIPT_MODE_ALWAYS_SCROLL = 2: 和上面不同的是,只要data变化刷新,就会自动scroll到bottom.
  1. 因为AdsListView会涉及到复杂的gesture交互,因此专门有一些touch的标志常量:
  • TOUCH_MODE_REST = -1:(mTouchMode的默认值) 表明当前不在 一次touch gesture交互的过程中
  • TOUCH_MODE_DOWN = 0: 表明收到了touch event,并且会进一步观察这个event是scroll还是tap.
  • TOUCH_MODE_TAP = 1: 表明这次touch已经被识别为一个tap, 现在会进一步观察是否是一个long press.
  • TOUCH_MODE_DONE_WAITING = 2: 表明已经从这次touch事务中等待到了要等待的动作,但是用户的手指还down在上面.
  • TOUCH_MODE_SCROLL = 3: 表明这次touch gesture是一个scroll.
  • TOUCH_MODE_FLING = 4:表明当前正处于fling的过程中.
  • TOUCH_MODE_OVERSCROLL = 5: overscroll了.
  • TOUCH_MODE_OVERFLING = 6: overfling了.
  1. layout影响最终显示相关的也有几个标志常量:
  • LAYOUT_NORMAL = 0:(mLayoutMode默认) 默认的正常layout.
  • LAYOUT_FORCE_TOP = 1: 一定要显示第一个item
  • LAYOUT_SET_SELECTION = 2: 一定要让被selected的那个item显示出来,只要显示出来就行,在哪无所谓.
  • LAYOUT_FORCE_BOTTOM: 一定要让最后一个item显示出来.
  • LAYOUT_SPECIFIC: 让selected的item显示在mSpecificTop这个位置,并且以此想下显示其他的item.
  • LAYOUT_SYNC = 5:
  • LAYOUT_MOVE_SELECTION = 6:
  1. 列表项可选的标志常量:
  • CHOICE_MODE_NONE = 0:(mChoiceActionMode默认) 正常的list,不会indciate出被选择的.
  • CHOICE_MODE_SINGLE = 1: 允许选一个.
  • CHOICE_MODE_MULTIPLE = 2: 允许选多个.
  • CHOICE_MODE_MULTIPLE_MODAL = 3: 在modal selection mode下允许多个.
  1. 除了常规的ListAdapter外,还有一个RemoteViewsAdapter在将AbsListView作为RemoteView使用时被用到.
  2. mDrawSelectorOnTop: 标识是否会显示出list selector(就是在itemView的前面或者后面draw一个图像,默认false).
  • setDrawSelectorOnTop(boolean onTop),这个函数只是简单的set值,不会触发重绘..
  • 要draw的drawable是由mSelector指定的,setSelector(Drawable sel)可以给其赋值.
  • useDefaultSelector()会调用setSelector设定一个默认的selector: com.android.internal.R.drawable.list_selector_background
  1. mSelectorPosition: 当前selector在list的位置:默认是INVALID_POSITION.还有一个mSelectorRect制定selector在被draw时的位置和尺寸
  2. RecycleBin mRecycler = new RecycleBin(): View回收器,回收用不到的view,这样在下次layout的时候不必重新new view了.
  3. mSelectionXXXPadding: 指定了 selector的padding.
  4. mListPadding = new Rect(): view自己的padding.
  5. View mScrollUp/mScrollDown: 在scroll时的上下indicator.
  6. mMotionPosition:接受到了touch down event的view在data set中的pos.
  7. mMotionViewOriginalTop: 接受到了touch down event时的垂直位置距离被touch 的iitemView的top的偏移(其实应该就是motionEVent在itemView中的坐标).
  8. mMotionX/mMotionY: down event的坐标.
  9. mLastY:上一次motionEvent的y坐标.
  10. mMotionCorrection: 一个阈值,在user move超过这个阈值以后,才开始scroll.
  11. VelocityTracker mVelocityTracker: 计算scroll速度用的.
  12. FlingRunnable mFlingRunnable, 处理fling中的一帧
  13. EditText mTextFilter: filter mode下对应的 EditText.(会detect该EditView的输入变化,也正一次,AdbListView才implements 了 TextWatcher),
  • mTextFilterEnabled标识是否支持filter.
  • mFiltered标识当前展现的view是不是基于被filter过的data.
  1. mSmoothScrollbarEnabled = true: 是否使用scrollBar.
  2. Rect mTouchFrame: 用来在child上面做hit testing.
  3. 检测longPress一般是通过post一个延迟runnable实现的:
  • CheckForLongPress mPendingCheckForLongPress: 最近post的check longpress的runnable, 如果post过的话.
  • mPendingCheckForTap: 同上
  • CheckForKeyLongPress mPendingCheckForKeyLongPress: 同上.
  1. mCacheColorHint: 标识该list的背景是solid, single-color, opaque的.
  2. int mLastScrollState = OnScrollListener.SCROLL_STATE_IDLE: 最近一次通过OnScrollListener通报给clients的scroll state.
  3. FastScroller mFastScroller:一个helper, 负责fast scroll时的thumb的渲染和控制.
  4. mActivePointerId = INVALID_POINTER: 多点touch时的有效 pointerId.
  5. mOverscrollDistance/mOverflingDistance: overscroll引发edge effects过程中的最大偏移距离.
  6. OnScrollListener提供了一个外界观测scroll状态的接口:
  • onScrollStateChanged(AbsListView view, int scrollState): 标识scroll状态的变化,如果已经在被scroll了,那么这个方法会被继续调用,并且是在scroll的下一frame前被调用, 一般里说,会在Adapter的getView(….)前被调用,三种状态:
  • SCROLL_STATE_IDLE = 0: 没有scroll.
  • SCROLL_STATE_TOUCH_SCROLL = 1: 正在被scroll
  • SCROLL_STATE_FLING = 2: 正在fling,并渐渐停止.
  • onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
    int totalItemCount): 这个方法在scroll之后会被调用
  1. initAbsListView()会从ViewConfiguration.get(mContext)中得到各种阈值:mTouchSlop/mMinimumVelocity/mMaximumVelocity/mOverscrollDistance/mOverflingDistance, 并将getContext().getResources().getDisplayMetrics().density作为自己的mDensityScale.
  2. requestLayoutIfNecessary(): 只有在有child的情况下才会进行:
  • resetList(): 会将当前所有的child都remove(因为已经发生了变化,所以需要这么做),然后将一堆的标识位reset,最后触发一个invalidate().
  • requestLayout(): 在这里被 override了:

if (!mBlockLayoutRequests && !mInLayout) {
super.requestLayout();
}
如果已经在onLayout过程中(onLayout的开头会mInLayout = true,结尾会mInLayout = false),或者block 了 layout 的request,就不会调用真正的requestLayout.

  1. invalidate()
  2. SavedState extends BaseSavedState: onSave/restoreInstance中用到的自定义的state. 为了使用,会override onSave/RestoreInstanceState并new 一个 SavedState 并填充完以后作为结果返回(onSaveInstanceState)/作为输入参数使用(onRestoreInstanceState).


举报

相关推荐

0 条评论