Drawable的state和View state

有时候会发生,针对View的状态和Drawable状态不相同的情况,这个是因为Drawable的state和View state不一样。可能是因为有别的地方去设置的Drawable的状态。

对于Drawable来说,其中设置背景的代码是

public void setBackgroundDrawable(Drawable background) {
        computeOpaqueFlags();
        if (background == mBackground) {
            return;
        }
        boolean requestLayout = false;
        mBackgroundResource = 0;
        /*
         * Regardless of whether we're setting a new background or not, we want
         * to clear the previous drawable.
         */
        if (mBackground != null) {
            mBackground.setCallback(null);
            unscheduleDrawable(mBackground);
        }
        if (background != null) {
            Rect padding = sThreadLocal.get();
            if (padding == null) {
                padding = new Rect();
                sThreadLocal.set(padding);
            }
            resetResolvedDrawables();
            background.setLayoutDirection(getLayoutDirection());
            if (background.getPadding(padding)) {
                resetResolvedPadding();
                switch (background.getLayoutDirection()) {
                    case LAYOUT_DIRECTION_RTL://界面从右到左边布局
                        mUserPaddingLeftInitial = padding.right;
                        mUserPaddingRightInitial = padding.left;
                        internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
                        break;
                    case LAYOUT_DIRECTION_LTR:
                    default:
                        mUserPaddingLeftInitial = padding.left;
                        mUserPaddingRightInitial = padding.right;
                        internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
                }
            }
            // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
            // if it has a different minimum size, we should layout again
            if (mBackground == null || mBackground.getMinimumHeight() != background.getMinimumHeight() ||
                    mBackground.getMinimumWidth() != background.getMinimumWidth()) {
                requestLayout = true;
            }
            background.setCallback(this);
            if (background.isStateful()) {
                background.setState(getDrawableState());//设置其中图片的状态,可以选择不可以选择的状态。然后把这个图片的引用给mBackground。上面还会设置图片圆角等。
            }
            background.setVisible(getVisibility() == VISIBLE, false);
            mBackground = background;
……………….//因为只是传递的引用所以如果background改变的时候,mBackground 也会发生改变。这个是java的浅拷贝
    }

通过View来中会有mBackgound对象,其中当View点击,设置不可以见的时候都会去设置,Background的state属性。

例如:

   protected void drawableStateChanged() {
        Drawable d = mBackground;
        if (d != null && d.isStateful()) {
            d.setState(getDrawableState());
        }
    }

也就是通过 setState去设置Drawable的属性。

mIconBackDrawable.setState(new int[] {android.R.attr.enabled,android.R.attr.state_focused});

当其中 new int[]{}的时候基本上不是很有作用,但是可以通过设置控制时候可以点击,可见之类的。

    public boolean setState(final int\[\] stateSet) {
        if (!Arrays.equals(mStateSet, stateSet)) {
            mStateSet = stateSet;
            return onStateChange(stateSet);
        }
        return false;
    }