天天看點

android gridview幾個重要屬性(android:listSelector自帶内部padding分析)

Android GridView幾個重要屬性的分析與使用,例如:android:listSelector,android:stretchMode,android:scrollbarStyle

一、android:scrollbarStyle  決定狀态條的位置

    常用屬性outsideOverlay,滾動條在最外層,gridview設定的padding在滾動條的内側

二、android:stretchMode  決定怎麼配置設定剩餘的空間

spacingWidth

     除去griditem和gridview的左右padding,剩餘的空間totalSpace用中間的空餘空間去擴充,這裡的中間的分割空間總數n = columns - 1,這n個空間平分totalSpace

spacingWidthUniform

     除去griditem和gridview的左右padding,剩餘的空間totalSpace用n= columns + 1個空間去平分。與spacingWidth的差別就是分割空間多了兩個,就是Gridview左右兩邊分别有一個,而且還不包括padding。

columnWidth

     除去gridview的左右padding和horizontalspacing,用列的寬度去填滿剩餘空間,就是把剩餘的空間平均分給每列的寬度。

三、android:listSelector   設定每個Item的按下效果,這個屬性有點坑,具體如下解釋

    很多時候我們都會自定義gridview的每個Item的布局,點選效果也會使用自己的,不使用系統的。正常情況下如果自定義item比每個Gridview内部的item的要小,那麼我們按下gridview的item時會響應系統的那個按下效果,但是如果我們自定義的item和gridview的item一樣大,而且設定了點選事件,這個時候就點不中系統的按下效果了。 那麼問題來了,本來視覺上沒什麼問題,但是我們發現gridview的兩邊多了一些padding(這裡即使設定了gridview的padding,這個padding也會累加),原來發現系統預設的listSelctor自帶有一個padding,這個padding會累加到gridview的padding上去。

    解決上面問題的辦法,自己設定一個listSelector去把系統的替換了。接下來看下這個listSelector怎麼影響那個padding的。

1. 系統方法AbsListView的setSelector中設定了一個變量mSelectionRightPadding 

public void setSelector(Drawable sel) {
    if (mSelector != null) {
        mSelector.setCallback(null);
        unscheduleDrawable(mSelector);
    }
    mSelector = sel;
    Rect padding = new Rect();
    sel.getPadding(padding);
    mSelectionLeftPadding = padding.left;
    mSelectionTopPadding = padding.top;
    mSelectionRightPadding = padding.right;
    mSelectionBottomPadding = padding.bottom;
    sel.setCallback(this);
    updateSelectorState();
}      

2. AbsListView的onMeasure中改變了mListPading的值,這裡真是fuck麼,搞一個臨時變量來改值,搞不懂要鬧那樣。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mSelector == null) {
        useDefaultSelector();
    }
    final Rect listPadding = mListPadding;
    listPadding.left = mSelectionLeftPadding + mPaddingLeft;
    listPadding.top = mSelectionTopPadding + mPaddingTop;
    listPadding.right = mSelectionRightPadding + mPaddingRight;
    listPadding.bottom = mSelectionBottomPadding + mPaddingBottom;
    // 省略其他代碼
}      

3. GridView的makeRow方法中把mListPading累加了

private View makeRow(int startPos, int y, boolean flow) {
    final int columnWidth = mColumnWidth;
    final int horizontalSpacing = mHorizontalSpacing;

    final boolean isLayoutRtl = isLayoutRtl();

    int last;
    int nextLeft;

    if (isLayoutRtl) {
        nextLeft = getWidth() - mListPadding.right - columnWidth -
        ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
    } else {
        nextLeft = mListPadding.left +
        ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
    }  // 這裡累加了,順便可以看到spacingWidthUniform熟悉的作用

    if (!mStackFromBottom) {
        last = Math.min(startPos + mNumColumns, mItemCount);
    } else {
        last = startPos + 1;
        startPos = Math.max(0, startPos - mNumColumns + 1);

        if (last - startPos < mNumColumns) {
            final int deltaLeft = (mNumColumns - (last - startPos)) * (columnWidth +                                        horizontalSpacing);
            nextLeft += (isLayoutRtl ? -1 : +1) * deltaLeft;
        }
    }
     // 省略其他代碼
}      

繼續閱讀