我有一种情况需要在onCreateDrawableState中动态地根据条件设置自定义按钮的setBackground。 所以我的代码就像这样
public class MyButton extends Button {
public boolean nightMode = false;
private Drawable dayBackground, nightBackgound;
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
setDuplicateParentStateEnabled(true);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.QITheme,
0, 0);
try {
dayBackground = a.getDrawable(R.styleable.MyTheme_dayBackground);
nightBackgound = a.getDrawable(R.styleable.MyTheme_nightBackground);
} finally {
a.recycle();
}
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
int[] state = super.onCreateDrawableState(extraSpace+1);
if (CurrentThemeManager.isNightMode()) {
if(nightBackgound != null)
setBackground(nightBackgound);
} else {
if(dayBackground != null)
setBackground(dayBackground);
}
return state;
}
}
但是由于setBackground间接调用onCreateDrawableState,因为无限递归调用而得到StackOverflowError
java.lang.StackOverflowError
at android.view.ViewGroup.onCreateDrawableState(ViewGroup.java:5370)
at android.view.View.onCreateDrawableState(View.java:14635)
at android.view.ViewGroup.onCreateDrawableState(ViewGroup.java:5370)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:69)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76)
at android.view.View.getDrawableState(View.java:14611)
at android.view.View.setBackgroundDrawable(View.java:14837)
at android.view.View.setBackground(View.java:14777)
at my.mytheme.widget.MyButton.onCreateDrawableState(MyButton.java:76
有人可以帮我解决这个StackOverflowError吗?
答案 0 :(得分:2)
您不应该从setBackground
致电onCreateDrawableState
。这是一种懒惰的方式。但是应该从drawable改变 state 。
像这样做饭:
<item android:state_checked="false"
android:drawable="@drawable/night_image" />
<item android:state_checked="true"
android:drawable="@drawable/day_image" />
在自定义视图中添加状态处理
class YourFancyView extends SomeView implement Checkable {
private static final int[] CHECKED_STATE_SET = {
android.R.attr.state_checked
};
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
@Override
public void setChecked(boolean checked) {
if(mChecked != checked) {
mChecked = checked;
refreshDrawableState();
}
}
下一步 - 编写任何合理的方式来设置checked
状态。
YourFancyView v = new YourFancyView();
if(itIsTime)v.setChecked(true);
这应该可以解决问题。
答案 1 :(得分:0)
我不确定这是否能解决你遇到的问题,但我认为你应该用setBackgroundDrawable()取代setBackground()