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(new int[] { android.R.attr.state_pressed }, pressedDrawable); mStateContainer.addState(View.PRESSED_STATE_SET, pressedDrawable); mStateContainer.addState(View.FOCUSED_STATE_SET, focusedDrawable); mStateContainer.addState(StateSet.WILD_CARD, defaultDrawable); this.setBackgroundDrawable(mStateContainer); }