我创建了一个扩展ViewGroup的类。此MyCustomViewGroup类的一个函数是作为嵌套类MyButton的容器,它扩展了Button。
我以正常方式从自定义AttributeSet设置MyCustomViewGroup的自定义属性。其中一个属性定义StateListDrawable以用于MyButton嵌套类的实例的背景。我将它存储在Class变量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 number 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);
这也没有解决问题。在我试图解决这个问题的研究中,我已阅读this article by Romain Guy on Drawable mutations。我原以为,由于StateListDrawable是Drawable的子类,我应该可以应用相同的方法,但我似乎无法让它工作。我错过了什么?
答案 0 :(得分:8)
你不能与多个视图共享一个SLD实例,每个视图需要一个SLD,抱歉
答案 1 :(得分:3)
在pskink回答之后,问题是您使用相同的Drawable
实例。当您将Drawable
设置为背景时,View
会将自己注册为Drawable
接收事件的监听器(以考虑Drawable
的新统计信息,还需要重绘View
)。因此,您的单个实例StateListDrawable
将始终将最后View
作为回调设置为背景。这就是为什么它适用于最后一个Button
,但当你对另一个Button
采取行动时,它也会重新绘制相同的Buttons
,因为Drawable
会在其回调中触发无效View
{{} 1}}。
您可以通过为每个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);
答案 2 :(得分: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());
但我不知道此代码的副作用。谁知道?随意发表评论或指出我的错误。