Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 詳細講解Android中的AbsListView的源碼

詳細講解Android中的AbsListView的源碼

編輯:關於Android編程

不知道各位童鞋們在開發的過程中有沒有感興趣過ListView是如何實現的呢?其實本身ListView的父類AbsListView才是關鍵,但是如果大家看過源碼的話,會發現AbsListView將近7000多行代碼,是不是頭大啊,呵呵,沒事,下面咱們就一起來看看吧。

我們先從類中的常量開始分析:

 

    public static final int TRANSCRIPT_MODE_DISABLED = 0;
    public static final int TRANSCRIPT_MODE_NORMAL = 1;
    public static final int TRANSCRIPT_MODE_ALWAYS_SCROLL = 2;
    static final int TOUCH_MODE_REST = -1;
    static final int TOUCH_MODE_DOWN = 0;
    static final int TOUCH_MODE_TAP = 1;
    static final int TOUCH_MODE_DONE_WAITING = 2;
    static final int TOUCH_MODE_SCROLL = 3;
    static final int TOUCH_MODE_FLING = 4;
    static final int TOUCH_MODE_OVERSCROLL = 5;
    static final int TOUCH_MODE_OVERFLING = 6;
    static final int LAYOUT_NORMAL = 0;
    static final int LAYOUT_FORCE_TOP = 1;
    static final int LAYOUT_SET_SELECTION = 2;
    static final int LAYOUT_FORCE_BOTTOM = 3;
    static final int LAYOUT_SPECIFIC = 4;
    static final int LAYOUT_SYNC = 5;
    static final int LAYOUT_MOVE_SELECTION = 6;
    public static final int CHOICE_MODE_NONE = 0;
    public static final int CHOICE_MODE_SINGLE = 1;
    public static final int CHOICE_MODE_MULTIPLE = 2;
    public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;
上面的含義分別如下:

 

1、禁止副本模式

2、當數據集合發生變化的通知被接受到,列表將會自動的滾向底部。但條件必須是最後一條數據已經出現在屏幕上

3、列表將會自動的滾動到底部,不論當前的數據是否可見。

4、猜測我們並不是在觸摸的手勢中間。

5、假設我們接收到一個touch的觸摸的事件,我們等待去看到它是否是一個滑動的手勢。

6、預測到當前的touch事件是一個tap事件,我們正在等待這是否是一個長按的事件。

7、其余的常量與此類此,在此省略了。

 

接下來我們來看一一批與視圖繪制相關的變量:

 

    Drawable mSelector;
    int mSelectorPosition = INVALID_POSITION;
    Rect mSelectorRect = new Rect();
    final RecycleBin mRecycler = new RecycleBin();
    int mSelectionLeftPadding = 0;
    int mSelectionTopPadding = 0;
    int mSelectionRightPadding = 0;

    int mSelectionBottomPadding = 0;
    Rect mListPadding = new Rect();
    int mWidthMeasureSpec = 0;
    View mScrollUp;
    View mScrollDown;
    boolean mCachingStarted;
    boolean mCachingActive;
    int mMotionPosition;
    int mMotionViewOriginalTop;
    int mMotionViewNewTop;

    int mMotionX;

    int mMotionY;

    int mTouchMode = TOUCH_MODE_REST;
    int mLastY;

    int mMotionCorrection;
    private VelocityTracker mVelocityTracker;

    private FlingRunnable mFlingRunnable;
    AbsPositionScroller mPositionScroller;

    int mSelectedTop = 0;

    boolean mStackFromBottom;
    boolean mScrollingCacheEnabled;

    boolean mFastScrollEnabled;
    boolean mFastScrollAlwaysVisible;
    private OnScrollListener mOnScrollListener;

上面的含義分別如下:

 

1、用來繪制選中項的圖片

2、列表中當前被選中的位置

3、在繪制的時刻定義選中的location與對應的尺寸

4、這個數據被設置,存儲未使用的視圖,它們將會被重用,在接下來的布局中,避免重用。

5、選中的padding的位置

6、向上滾動的標志與向下滾動的標志的視圖

7、當這個視圖在滾動的時候,這個標志位被設置為true,預示著繪制緩存的子類在其子類上將會是能夠的。

8、獲取向下的移動的位置

9、其余的變量的注解省略。

 

接下來,我們看幾個接口的定義

1、OnScrollListener

這個接口定義的是當列表或者是九宮格滾動的時候的回調。

在這個接口中存在下面的幾個常量

 

public static int SCROLL_STATE_IDLE = 0;
public static int SCROLL_STATE_TOUCH_SCROLL = 1;
public static int SCROLL_STATE_FLING = 2;
分別指代的是當前的列表處於靜止、手指處於觸摸狀態的滑動以及手指離開的減速滑動並趨向於靜止。

 

 

其中接口中還定義了兩個函數:

1、onScrollStateChanged

2、onScroll

 

第一個視圖是當視圖滾動正准備進行時候的回調

第二個視圖是當視圖的滾動已經結束的回調

 

2、SelectionBoundsAdjuster

這個接口的含義是允許當前列表項的頂級視圖實現這個接口去修改它的展示的邊界區域。

 

接下來的代碼選取幾個Api來看一下:

1、setFastScrollerEnabledUiThread

 

private void setFastScrollerEnabledUiThread(boolean enabled) {
        if (mFastScroll != null) {
            mFastScroll.setEnabled(enabled);
        } else if (enabled) {
            mFastScroll = new FastScroller(this, mFastScrollStyle);
            mFastScroll.setEnabled(true);
        }

        resolvePadding();

        if (mFastScroll != null) {
            mFastScroll.updateLayout();
        }
    }

這個方法的功能是顯而易見的,操縱的對象是FastScroller,設置是否支持快速的滑動,然後再進行重新繪制視圖。

 

 

下面的幾個方法是計算滾動區域與展示的效果的方法,我們選取幾個來看一下:

 

 @Override
    protected int computeVerticalScrollExtent() {
        final int count = getChildCount();
        if (count > 0) {
            if (mSmoothScrollbarEnabled) {
                int extent = count * 100;

                View view = getChildAt(0);
                final int top = view.getTop();
                int height = view.getHeight();
                if (height > 0) {
                    extent += (top * 100) / height;
                }

                view = getChildAt(count - 1);
                final int bottom = view.getBottom();
                height = view.getHeight();
                if (height > 0) {
                    extent -= ((bottom - getHeight()) * 100) / height;
                }

                return extent;
            } else {
                return 1;
            }
        }
        return 0;
    }

這個是計算垂直方向上的滾動的區域。

 

這個算法我們可以看一下

1、

extent += (top * 100) / height;
這裡面的100我們可以理解為系統假設單個的列表的選項的高度是100,本著多退少補的原則,不論height是大於100還是小於100, 100 / height,得到的數值可以理解為是縮放因子 scaleFactor, top * scaleFactor 計算得到的是最終需要多加的邊距。

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved