適配器模式

前言:

定義:適配器模式是把一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使得原本因接口不匹配而無法一起工作的兩個(gè)類能協(xié)同工作。

適配器是將兩個(gè)不兼容的類融合在一起,它有點(diǎn)像粘合劑,將不同的東西通過一個(gè)轉(zhuǎn)換使得它們能夠協(xié)作起來.


Android源碼的適配器模式

1.首先看ListView的父類,AbsListView。

public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
        ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
        ViewTreeObserver.OnTouchModeChangeListener,
        RemoteViewsAdapter.RemoteAdapterConnectionCallback {
    ListAdapter mAdapter;
    
    /**
     * 關(guān)聯(lián)到 Window時(shí),通過 Adapter來獲取 Item View 的數(shù)量、布局、數(shù)據(jù)等
     */
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        final ViewTreeObserver treeObserver = getViewTreeObserver();
        treeObserver.addOnTouchModeChangeListener(this);
        if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) {
            treeObserver.addOnGlobalLayoutListener(this);
        }

        /**
         * 給設(shè)配器注冊(cè)一個(gè)觀察者
         */
        if (mAdapter != null && mDataSetObserver == null) {
            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            // Data may have changed while we were detached. Refresh.
            mDataChanged = true;
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
        }
    }
    
    
    /**
     * Subclasses should NOT override this method but
     *  {@link #layoutChildren()} instead.
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        mInLayout = true;

        final int childCount = getChildCount();
        if (changed) {
            for (int i = 0; i < childCount; i++) {
                getChildAt(i).forceLayout();
            }
            mRecycler.markChildrenDirty();
        }

        //布局 Child View
        layoutChildren();
        mInLayout = false;

        mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;

        // TODO: Move somewhere sane. This doesn't belong in onLayout().
        if (mFastScroll != null) {
            mFastScroll.onItemCountChanged(getChildCount(), mItemCount);
        }
    }
}

AbsListView 定義了集合視圖的邏輯框架,比如 Adapter模式的應(yīng)用、復(fù)用 Item View 的邏輯、布局自視圖的邏輯等。

2.ListView 覆寫了的 layoutChildren。

ListView 覆寫了 AbsListView 中的 layoutChildren。在 layoutChildren 中根據(jù)布局模式來布局 Item View,例如有從上而下,也有從下而上開始布局的(qq聊天的氣泡布局,最新的消息到窗口的最底部)。我們來看看這兩種實(shí)現(xiàn)

  1. 從上而下填充 Item View(只是其中的一種方式)
 /**
 * Fills the list from pos down to the end of the list view.
 *
 * @param pos The first position to put in the list
 *
 * @param nextTop The location where the top of the item associated with pos
 *        should be drawn
 *
 * @return The view that is currently selected, if it happens to be in the
 *         range that we draw.
 */
private View fillDown(int pos, int nextTop) {
    View selectedView = null;

    int end = (mBottom - mTop);
    if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
        end -= mListPadding.bottom;
    }

    while (nextTop < end && pos < mItemCount) {
        // is this the selected item?
        boolean selected = pos == mSelectedPosition;
        View child = makeAndAddView(pos, nextTop, true, mListPadding.left, selected);

        nextTop = child.getBottom() + mDividerHeight;
        if (selected) {
            selectedView = child;
        }
        pos++;
    }

    setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);
    return selectedView;
}

總結(jié):

ListView 等集合控件通過 Adapter來獲取 Item View 的數(shù)量、布局、數(shù)據(jù)等,在這里尤為重要的就是 View類型的對(duì)象,也就是 Item View.由于它返回的是一個(gè) View抽象,而千變?nèi)f化的 UI視圖都是 View 的子類,通過依賴抽象原則和 Adapter 模式就將 Item View 的變化隔離了,保證了 AbsListView 類族的高度可定制化。在獲取到 View之后,將這些 View 通過特定的布局方式設(shè)置到對(duì)應(yīng)的位置,再加上 Item View 的復(fù)用機(jī)制,整個(gè) ListView就運(yùn)轉(zhuǎn)起來了。

深度拓展 RecyclerView

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容