4

我创建了一个扩展 ViewGroup 的类。此 MyCustomViewGroup 类的功能之一是充当扩展 Button 的嵌套类 MyButton 的容器。

我以正常方式从自定义 AttributeSet 设置 MyCustomViewGroup 的自定义属性。其中一个属性定义了用于 MyButton 嵌套类实例背景的 StateListDrawable。我将它存储在一个类变量 mMyButtonBackground 中。

public class MyCustomViewGroup extends ViewGroup {
    private Drawable mMyButtonBackground;
    ...

每次我在 MyCustomViewGroup 中创建 MyButton 的新实例时,我都会将其设置为背景。

    MyButton myButton = new MyButton(context);
    myButton.setBackground(mMyButtonBackground);

在运行时,StateListDrawable 似乎只适用于最近添加的 MyButton 实例。

例如,假设我在 MyCustomViewGroup 中创建了 4 个 MyButton 实例。如果我单击 MyButton 数字 4,它的背景会发生在 StateListDrawable 中定义的变化。如果我单击 MyButton 1 到 3,它们的背景不会改变,但 MyButton 数字 4 会改​​变。

从逻辑上讲,这表明这是一个可变性问题。所有 MyButton 实例共享存储在 mMyButtonBackground 中的相同 StateListDrawable。考虑到这一点,我尝试过:

    MyButton myButton = new MyButton(context);
    Drawable myButtonBackground = mMyButtonBackground.mutate();
    myButton.setBackground(myButtonBackground);

但这并没有解决问题。我还尝试将其专门转换为 StateListDrawable:

    MyButton myButton = new MyButton(context);
    StateListDrawable myButtonBackground = (StateListDrawable)mMyButtonBackground.mutate();
    myButton.setBackground(myButtonBackground);

这也没有解决问题。在我试图解决这个问题的研究中,我已经阅读了 Romain Guy 关于 Drawable mutation 的这篇文章。我会认为由于 StateListDrawable 是 Drawable 的子类,我应该能够应用相同的方法,但我似乎无法让它工作。我错过了什么?

4

3 回答 3

8

您不能与多个视图共享一个 SLD 实例,每个视图需要一个 SLD,抱歉

于 2013-09-23T08:40:13.420 回答
3

在 pskink 回答之后,问题是您使用相同的Drawable实例。当您将 设置Drawable为背景时,View将自己注册为接收事件的侦听器Drawable(考虑到 a 的新状态Drawable,也需要重绘View)。因此,您的单个实例StateListDrawable将始终作为回调,最后一个View设置为背景。这就是为什么它对最后一个起作用的原因,但是当您对另一个采取行动时Button,它也会重新绘制相同的内容,因为它会在其回调上触发无效。ButtonButtonsDrawableView

您可以通过StateListDrawable为每个Button. 在 wrapper 容器中,您可以只传递一个带有 a 的属性,该属性String代表StateListDrawable要用作背景的名称,存储它并在创建 new 时使用它Buttons

String mBtnDrawable = ""; //initialize in the constructor

// creating new Buttons
MyButton myButton = new MyButton(context);
int drawableId = getContext().getResources().getIdentifier(mBtnDrawable, "drawable", getContext().getPackageName());
StateListDrawable bck = (StateListDrawable) getContext().getResources().getDrawable(drawableId); // maybe also mutate it?
myButton.setBackground(bck);
于 2013-09-23T08:55:13.753 回答
1

根据 Resources 类的作用(Resources.java),我发现下面的代码可以解决您的问题。

Drawable selector = res.getDrawable(R.drawable.setting_btn_pressed_selector);
view1.setBackgroundDrawable(selector.getConstantState().newDrawable());
view2.setBackgroundDrawable(selector.getConstantState().newDrawable());
view3.setBackgroundDrawable(selector.getConstantState().newDrawable());

但我不知道这段代码的副作用。有人知道吗?随时发表任何评论或指出我的错误。

于 2015-09-15T13:24:12.487 回答