我创建了一个扩展viewgroup的类。这个mycustomviewgroup类的一个函数充当扩展button的嵌套类mybutton的容器。
我以正常方式从自定义属性集设置mycustomviewgroup的自定义属性。其中一个属性定义了stateListDrawable,可用于MyButton嵌套类实例的背景。我将其存储在类变量mmybuttonbackground中。
public class MyCustomViewGroup extends ViewGroup {
private Drawable mMyButtonBackground;
...
每次在mycustomviewgroup中创建mybutton的新实例时,我都会设置它的背景。
MyButton myButton = new MyButton(context);
myButton.setBackground(mMyButtonBackground);
在运行时,stateListDrawable似乎只适用于最近添加的myButton实例。
例如,假设我在mycustomviewgroup中创建了4个mybutton实例。如果我单击MyButton4,它的后台更改将在StateListDrawable中定义。如果我点击MyButton1到3,它们的背景不会改变,但MyButton4的背景会改变。
从逻辑上讲,这表明这是一个易变的问题。所有MyButton实例共享存储在mmyButtonBackground中的同一StateListDrawable。考虑到这一点,我试过:
MyButton myButton = new MyButton(context);
Drawable myButtonBackground = mMyButtonBackground.mutate();
myButton.setBackground(myButtonBackground);
但这并没有解决问题。我也试着把它具体地描述成一个有状态的图表:
MyButton myButton = new MyButton(context);
StateListDrawable myButtonBackground = (StateListDrawable)mMyButtonBackground.mutate();
myButton.setBackground(myButtonBackground);
这也没有解决问题。在我试图解决这个问题的研究中,我读过this article by Romain Guy on Drawable mutations。我本以为既然stateListDrawable是Drawable的一个子类,我应该可以应用同样的方法,但我似乎无法使它工作。我错过了什么?
最佳答案
根据pskink的答案,问题是您使用了相同的Drawable
实例。当您将Drawable
设置为背景时,View
将注册为该Drawable
接收事件的侦听器(考虑到Drawable
的新状态,还需要重新绘制View
)。因此,您的单个实例StateListDrawable
将始终具有最后一个设置为background的View
作为回调。这就是它在最后一个Button
中工作的原因,但当您对另一个Button
执行操作时,它也会重绘相同的Buttons
,因为Drawable
在其回调View
中触发无效。
您只需为每个StateListDrawable
创建一个新的Button
,就可以避免这种情况。在包装容器中,您可以传递一个属性,该属性的String
表示要用作背景的StateListDrawable
的名称,存储它并在创建新的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);