Android Widget源碼分析系列文章之AbsListView
- AbsListView的源碼剖析
-
- 繼承的類
- 實作的接口
- 相關的成員變量
- 内部定義的接口
-
- OnScrollListener
- SelectionBoundsAdjuster
- 構造函數
- 成員函數
-
- initAbsListView
- setOverScrollMode
- performItemClick
- contentFits
- setFastScrollAlwaysVisible
- pointToPosition
AbsListView的源碼剖析
這是一個基本的類,可以被用來實作虛拟化的清單。一個清單沒有一個空間的定義在這裡。例如,這個類的子類展示了清單的内容以九宮格、旋轉木馬或者是堆棧。
繼承的類
AdapterView
實作的接口
- TextWatcher ,監聽字元的變化
- ViewTreeObserver.OnGlobalLayoutListener,OnGlobalLayoutListener 是ViewTreeObserver的内部類,當一個視圖樹的布局發生改變時,可以被ViewTreeObserver監聽到,這是一個注冊監聽視圖樹的觀察者(observer),在視圖樹的全局事件改變時得到通知。ViewTreeObserver不能直接執行個體化,而是通過getViewTreeObserver()獲得。
- Filter.FilterListener,用一個過濾的模式,限制輸入的字元的内容,内部的函數是通知過濾操作的結束。
- ViewTreeObserver.OnTouchModeChangeListener,注冊一個觀察者來監聽視圖樹,當視圖樹的布局、視圖樹的焦點、視圖樹将要繪制、視圖樹滾動等發生改變時,ViewTreeObserver都會收到通知,ViewTreeObserver不能被執行個體化,可以調用View.getViewTreeObserver()來獲得。
- RemoteViewAdapter.RemoteAdapterConnectionCallback,一個接口針對RemoteAdapter 去通知其他的類當這個Adapters被真正的連接配接到他們真實的服務,或者是真實的解除連接配接。
相關的成員變量
逐一的對這個類中的定義的成員變量進行定義,基本意思以及功能作用。
- TRANSCRIPT_MODE_DISABLED, 這是一個public類型修飾的常量。表面的意思是禁止文字記錄的模式,實際上的意思是不允許自動滾動到使用者指定的位置。
- TRANSCRIPT_MODE_NORMAL,這是public類型修飾的常量。這個清單将會自動滾動到底部,當一個資料集合改變的通知被收到,并且隻有這個最後一個條目在螢幕上是真實可見的時候。
- TRANSCRIPT_MODE_ALWAYS_SCROLL,這是public類型修飾的常量。這個清單将會自動滾動到底部,不論目前螢幕上可見的條目是什麼。
- TOUCH_MODE_REST,預測我們并不是處于手指觸摸的中間。
- TOUCH_MODE_DONE_WAITING,預測我們已經等待每一件我們能夠等待的事情。但是這個使用者的手指始終是出于按下的狀态。
- TOUCH_MODE_SCROLL,預測使用者的手指是處于滾動的狀态。
- TOUCH_MODE_FLING,預測目前的視圖是處于被翻動的狀态。
- TOUCH_MODE_OVERSCROLL,預測這個手勢是過度的滾動,是一種滾動超過了開始或者是結束。
- TOUCH_MODE_OVERFLING,達到了邊緣,并且繪制回彈的效果。
- LAYOUT_NORMAL,普通的布局,經常一個來自于視圖系統的沒有請求的布局。
- LAYOUT_FORCE_TOP,顯示第一個條目。
- LAYOUT_SET_SELECTION ,強制選中的條目到螢幕指定的位置。
- LAYOUT_FORCE_BOTTOM,顯示最後一個條目。
- LAYOUT_SPECIFIC,建立一個選中的條目,呈現在一個指定的位置,并且建構這個視圖的剩餘的部分從這裡開始。這個頂部是被特殊的指定。
- LAYOUT_SYNC,布局與資料的改變同步發生了變化,恢複同步的位置,去讓他的頂部在他指定的位置。
- LAYOUT_MOVE_SELECTION,布局作為使用航海的鑰匙的結果。
- CHOICE_MODE_NONE,普通的清單,沒有預測的選擇。
- CHOICE_MODE_SINGLE,清單支援一個選擇。
- CHOICE_MODE_MULTIPLE,清單支援多個選擇。
- CHOICE_MODE_MULTIPLE_MODAL,這個清單支援多個選擇在一個模态的選擇模式。
- mOwnerThread,對應的是視圖被建立的線程。
- mChoiceMode,控制是否/怎樣這個使用者也許選擇/檢測在清單中的條目。
- mCheckedItemCount,目前有多少清單的條目被選中。
- mDrawSelectorOnTop,預測是否這個清單的選擇器應該繪制在子節點頂部還是底部。
- mSelector,圖檔用來繪制選擇器。
- mSelectorPosition,目前被選中的條目在清單中的位置。
- mRecycler,這個資料集合用來存儲沒有被使用的視圖,這些視圖在接下來的布局中可能被用到,避免建立新的視圖的對象。
- mVelocityTracker,決定了滾動的速度。
- mScrollingCacheEnabled,當設定位true, 這個清單将會自動丢棄子視圖的緩存,當滾動的時候。
- mSmoothScrollbarEnabled,判斷是基于像素的滾動,還是基于條目的滾動。
- mFastScroll,幫助類的對象繪制和控制快速滾動的滑塊。
内部定義的接口
OnScrollListener
- SCROLL_STATE_IDLE,視圖目前處于靜止的狀态。
- SCROLL_STATE_TOUCH_SCROLL,使用者通過觸摸滾動視圖,并且使用者目前的手指還是處于螢幕上。
- SCROLL_STATE_FLING,使用者之前已經通過觸摸,操作了一次滑動,目前處于滑動狀态,即将停止。
- onScrollStateChanged,回調方法将會被觸發,當清單視圖或者是九宮格的視圖被滾動。這個方法将會被調用當滾動的視圖的下一個資料幀将會被繪制。
- onScroll,當滾動行為結束後被調用。
SelectionBoundsAdjuster
- adjustListItemSelectionBounds,允許清單的條目去調整他被選中的矩形的邊界。
構造函數
- initAbsListView, 初始化清單的相關的元件。
- mOwnerThread = Thread.currentThread(),建立目前UI操作所在的線程。
- setVerticalScrollBarEnabled(true),設定允許顯示垂直的滾動條。
- initializeScrollbarsInternal,初始化垂直的滾動條的内部的業務邏輯。
成員函數
initAbsListView
- 代碼片段
// Setting focusable in touch mode will set the focusable property to true
setClickable(true);
setFocusableInTouchMode(true);
setWillNotDraw(false);
setAlwaysDrawnWithCacheEnabled(false);
setScrollingCacheEnabled(true);
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
mDensityScale = getContext().getResources().getDisplayMetrics().density;
- setClickable(true),設定目前的UI是可以被點選的
- setFocusableInTouchMode(true),設定目前的UI在觸摸的模式下是可以擷取焦點的。
- setWillNotDraw,如果這個View控件在他自己的内部沒有做任何的繪制,設定這個标志位允許以後的優化。
- setAlwaysDrawnWithCacheEnabled,預測是否這個ViewGroup是否将會總是嘗試繪制它的子節點使用它們自己的緩存。這個屬性可以被設定位true,當這個緩存的渲染略微不同于子節點的正常的渲染。渲染是可以不同的,比如,當這個緩存的品質被設定為低。當設定屬性是被禁用,這個ViewGroup将會使用它的子節點的繪制的緩存,僅僅當被詢問的時候。這個是它的子類的任務去告訴ViewGroup什麼時候開始使用這個繪制的緩存,以及什麼時候停止使用。
- 剩下的幾個屬性的初始化,包括觸摸的門檻值、最小以及最大的速度、滑動的最大的區間以及分辨率的初始化。
setOverScrollMode
在這個函數中,判斷是否允許使用者滑動超過邊界,這也就決定了mEdgeGlowTop以及mEdgeGlowBottom是否進行初始化。
performItemClick
contentFits
傳回true,如果清單的内容目前完全是在視圖的邊界内。
setFastScrollAlwaysVisible
設定是否這個快速的緩動應該被展示,而不是标準的滑動塊。這将決定了是否允許使用快速滑動。
if (isOwnerThread()) {
setFastScrollerAlwaysVisibleUiThread(alwaysShow);
} else {
post(new Runnable() {
@Override
public void run() {
setFastScrollerAlwaysVisibleUiThread(alwaysShow);
}
});
}
邏輯上的線程切換,值得代碼的借鑒。
pointToPosition
将一個坐标點轉換位一個清單的條目的索引。
public int pointToPosition(int x, int y) {
Rect frame = mTouchFrame;
if (frame == null) {
mTouchFrame = new Rect();
frame = mTouchFrame;
}
final int count = getChildCount();
for (int i = count - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
child.getHitRect(frame);
if (frame.contains(x, y)) {
return mFirstPosition + i;
}
}
}
return INVALID_POSITION;
}