问题
I am trying to remove an ImageButton's background in only the default state. I'd like the pressed and selected states to behave as usual so that they look correct on different devices, which use different colors for the pressed and selected states.
Is there any way to set an ImageButton's background default state's drawable without affecting the pressed and selected states?
I've tried to do this with a selector, but it does not appear to allow you to use the default drawables for some states - you have to set all the states yourself. Since there's no API to retrieve the device's default pressed/selected drawables, I don't know what to set the pressed/selected states to.
I also tried getting the StateListDrawable object for the button that the system creates when you are not using a selector and then modify it change the default state. That didn't work either.
I seems that on Android, if you want to change the drawable for one state of a button, then you must set all the states, and thus cannot preserve the default drawables for the other states. Is this correct?
Thanks! -Tom B.
回答1:
Tom,
It's true that if you override the default state you also have to override the pressed and focused states. The reason is that the default android drawable is a selector, and so overriding it with a static drawable means that you lose the state information for pressed and focused states as you only have one drawable specified for it. It's super easy to implement a custom selector, though. Do something like this:
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custombutton">
<item
android:state_focused="true"
android:drawable="@drawable/focused_button" />
<item
android:state_pressed="true"
android:drawable="@drawable/pressed_button" />
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/normal_button" />
</selector>
Put this in your drawables directory, and load it like a normal drawable for the background of the ImageButton. The hardest part for me is designing the actual images.
Edit:
Just did some digging into the source of EditText, and this is how they set the background drawable:
public EditText(/*Context context, AttributeSet attrs, int defStyle*/) {
super(/*context, attrs, defStyle*/);
StateListDrawable mStateContainer = new StateListDrawable();
ShapeDrawable pressedDrawable = new ShapeDrawable(new RoundRectShape(10,10));
pressedDrawable.getPaint().setStyle(Paint.FILL);
pressedDrawable.getPaint().setColor(0xEDEFF1);
ShapeDrawable focusedDrawable = new ShapeDrawable(new RoundRectShape(10,10));
focusedDrawable.getPaint().setStyle(Paint.FILL);
focusedDrawable.getPaint().setColor(0x5A8AC1);
ShapeDrawable defaultDrawable = new ShapeDrawable(new RoundRectShape(10,10));
defaultDrawable.getPaint().setStyle(Paint.FILL);
defaultDrawable.getPaint().setColor(Color.GRAY);
mStateContainer.addState(View.PRESSED_STATE_SET, pressedDrawable);
mStateContainer.addState(View.FOCUSED_STATE_SET, focusedDrawable);
mStateContainer.addState(StateSet.WILD_CARD, defaultDrawable);
this.setBackgroundDrawable(mStateContainer);
}
I'm sure you could adapt the idea to your purposes. Here is the page I found it on:
http://www.google.com/codesearch/p?hl=en#ML2Ie1A679g/src/android/widget/EditText.java
回答2:
StateListDrawable replace = new StateListDrawable();
Drawable old = getBackground();
replace.addState(FOCUSED_STATE_SET, old);
replace.addState(SELECTED_STATE_SET, old);
replace.addState(PRESSED_STATE_SET, old);
replace.addState(StateSet.WILD_CARD, new ColorDrawable(Color.TRANSPARENT));
if (Build.VERSION.SDK_INT >= 16) {
setBackground(replace);
} else {
setBackgroundDrawable(replace);
}
来源:https://stackoverflow.com/questions/3859144/how-to-modify-the-default-button-state-in-android-without-affecting-the-pressed