StateListDrawable无法工作

3

我正在尝试以编程方式设置StateListDrawable作为我的自定义视图的背景,用于一个库项目。这是我的操作:

final TypedArray a = getContext().obtainStyledAttributes(attrs,
            R.styleable.ActionBar);
    int firstColor = a.getColor(
            R.styleable.ActionBar_backgroundGradientFirstColor, 0xff000000);
    int secondColor = a
            .getColor(R.styleable.ActionBar_backgroundGradientSecondColor,
                    0xff000000);
    int textViewColor = a.getColor(R.styleable.ActionBar_titleColor,
            0xffffffff);
    int onClickColor = a.getColor(
            R.styleable.ActionBar_backgroundClickedColor, 0xff999999);
    a.recycle();

    StateListDrawable sld = new StateListDrawable();
    GradientDrawable drawable = new GradientDrawable(
            Orientation.TOP_BOTTOM, new int[] { firstColor, secondColor });
    sld.addState(new int[] { android.R.attr.state_enabled },
            new ColorDrawable(onClickColor));
    sld.addState(new int[] { android.R.attr.state_pressed }, drawable);

    action2.setBackgroundDrawable(sld);
    action3.setBackgroundDrawable(sld);
    actionBack.setBackgroundDrawable(sld);
    pb.setBackgroundDrawable(drawable);
    tv.setBackgroundDrawable(drawable);
    tv.setTextColor(textViewColor);

然而,这并没有起作用:它总是绘制启用状态。当我按下按钮时,我希望它绘制按下状态。我做错了什么?

以防万一:由于我希望这个UI库尽可能可定制化,所以不考虑使用XML(用户应该能够通过他们的XML自定义它)。 - Charlie-Blake
2个回答

20

我猜按钮在被按下的时候仍然是启用的?

你可以尝试颠倒顺序:

sld.addState(new int[] { android.R.attr.state_pressed }, drawable);
sld.addState(new int[] { android.R.attr.state_enabled },
        new ColorDrawable(onClickColor));

可能是绘制第一个当前有效的状态。

如果您想在按下时使用不同的背景,并为所有其他情况使用另一个背景,您也可以使用:

sld.addState(new int[] { android.R.attr.state_pressed }, drawable);
sld.addState(new int[] { StateSet.WILD_CARD },
        new ColorDrawable(onClickColor));

补充:我刚刚测试了一下,以下的测试代码对我有效:

Button testButton = new Button(context);
            testButton.setText("Test");
            StateListDrawable sld = new StateListDrawable();
            GradientDrawable drawable = new GradientDrawable(
                    Orientation.TOP_BOTTOM, new int[] { Color.BLUE, Color.RED });
            sld.addState(new int[] { android.R.attr.state_pressed }, drawable);
            sld.addState(StateSet.WILD_CARD, new ColorDrawable(Color.YELLOW));
            testButton.setBackgroundDrawable(sld);          
            mainLayout.addView(testButton);

不管哪种方法,只要我按下按钮,它们就一直处于state_enabled或WILD_CARD状态。 - Charlie-Blake
我刚刚亲自测试了一下,它对我来说绝对有效。如果您使用自定义按钮视图,也许您应该调查一下是否由于某些原因它从未进入按下状态?还要注意,只有在您用手指按下按钮时,按下的可绘制才会出现。当您释放按钮上的手指时,按钮不再被按下,因此默认背景将再次绘制。 - Hendrik
好的,我设法让它工作了。但是,每当我触摸按钮时,整个父布局都会被按下。我在该布局中的所有视图子项上使用相同的可绘制Sld,这是问题吗? - Charlie-Blake
1
你应该为每个视图使用单独的 SLD。否则,SLD 将被一个视图触发,然后在使用它的每个视图上重新绘制。 - Hendrik
4
非常重要:绘制第一个有效状态。这是由您添加它们的顺序决定的。(首先添加空状态会导致痛苦和折磨)。 - c2knaps
显示剩余2条评论

0
顺序很重要。将默认状态定义放在最后。 这样做是行不通的:
            stateListDrawable.addState(StateSet.WILD_CARD,  ColorDrawable(Color.YELLOW))
            stateListDrawable.addState(statePressedDrawable,  ColorDrawable(Color.BLUE))

            stateListDrawable.addState(statePressedDrawable,  ColorDrawable(Color.YELLOW))
            stateListDrawable.addState(StateSet.WILD_CARD,  ColorDrawable(Color.BLUE))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接