關於爲listview設置listSelector不起作用的問題

背景:今天寫一個菜單列表,爲listview設置了點擊效果,但是運行時發現明明設置了但是卻沒有生效,以爲手機問題,重新換了一個設備發現還是不行。我也是醉了,翻了翻源碼,發現了一點貓膩。

 @Override
    protected void dispatchDraw(Canvas canvas) {
        int saveCount = 0;
        final boolean clipToPadding = (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
        if (clipToPadding) {
            saveCount = canvas.save();
            final int scrollX = mScrollX;
            final int scrollY = mScrollY;
            canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop,
                    scrollX + mRight - mLeft - mPaddingRight,
                    scrollY + mBottom - mTop - mPaddingBottom);
            mGroupFlags &= ~CLIP_TO_PADDING_MASK;
        }

        final boolean drawSelectorOnTop = mDrawSelectorOnTop;
        if (!drawSelectorOnTop) {
            drawSelector(canvas);
        }

        super.dispatchDraw(canvas);

        if (drawSelectorOnTop) {
            drawSelector(canvas);
        }

        if (clipToPadding) {
            canvas.restoreToCount(saveCount);
            mGroupFlags |= CLIP_TO_PADDING_MASK;
        }
    }
dispatchDraw被調用時,先會去判斷mDrawSelectorOnTop的值,如果爲false,會先繪製selector,後遍歷子view進行子view繪製,而我的代碼中,子view是充滿item的,並且設置了背景,導致子view將點擊效果完全遮蓋。上面代碼中drawSelectorOnTop進行了兩次判斷

<span style="white-space:pre">	</span>if (!drawSelectorOnTop) {
            drawSelector(canvas);
        }

        super.dispatchDraw(canvas);

        if (drawSelectorOnTop) {
            drawSelector(canvas);
        }
drawSelectorOnTop這個變量,可以看出設置是否在頂部繪製,不在頂部繪製則先繪製Selector後進行dispatchDraw,反之先dispatchDraw繪製子view後繪製Selector.

解決辦法:mDrawSelectorOnTop = a.getBoolean(
                com.android.internal.R.styleable.AbsListView_drawSelectorOnTop, false);

源碼中的構造方法解析xml時,會去獲取一個叫drawSelectorOnTop的屬性值,在xml中敲了一下,果然有。

源碼中還有:

/**
     * Controls whether the selection highlight drawable should be drawn on top of the item or
     * behind it.
     *
     * @param onTop If true, the selector will be drawn on the item it is highlighting. The default
     *        is false.
     *
     * @attr ref android.R.styleable#AbsListView_drawSelectorOnTop
     */
    public void setDrawSelectorOnTop(boolean onTop) {
        mDrawSelectorOnTop = onTop;
    }

這麼一看,就很清晰了。註釋也說的很明白。

記錄一下這個問題,也希望對遇到這個問題的人有幫助


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章