I've created a custom view which should change it's background image when pressed, highlighted or disabled. The app runs but the button doesn't change it's background.
here's my code:
public class CustomImageButton extends View {
public CustomImageButton(Context context) {
super(context);
setFocusable(true);
setClickable(true);
}
public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setClickable(true);
}
public CustomImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setClickable(true);
}
protected Drawable background = super.getBackground();
@Override
public void setBackgroundDrawable(Drawable d) {
// Replace the original background drawable (e.g. image) with a LayerDrawable that
// contains the original drawable slightly edited.
CustomImageButtonBackgroundDrawable layer = new CustomImageButtonBackgroundDrawable(d);
super.setBackgroundDrawable(layer);
}
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 int drawableWidth = super.getBackground().getMinimumWidth();
 int drawableHeight = super.getBackground().getMinimumHeight();
 setMeasuredDimension(drawableWidth, drawableHeight);
}
protected class CustomImageButtonBackgroundDrawable extends LayerDrawable { 
    protected Drawable lowerlayer;
    protected Drawable _highlightedDrawable;
    protected int _disabledAlpha = 100;
    protected Drawable _pressedDrawable;
    public CustomImageButtonBackgroundDrawable(Drawable d) {
          super(new Drawable[] { d });
    }
    @Override
    protected boolean onStateChange(int[] states) {
      boolean enabled = false;
      boolean highlighted = false;
      boolean pressed = false;
      for (int state : states) {
        if (state == android.R.attr.state_enabled)
            enabled = true;
        else if (state == android.R.attr.state_selected)
            highlighted = true;
        else if (state == android.R.attr.state_pressed)
            pressed = true;
      }
      mutate();
      if (enabled && highlighted) {
        ColorFilter colourFilter = new LightingColorFilter(Color.YELLOW, 1);
        ScaleDrawable resizedImage = new ScaleDrawable(background, 0, 1.25f, 1.25f);
        lowerlayer = resizedImage.getDrawable();
        lowerlayer.setColorFilter(colourFilter);
        Drawable[] aD = new Drawable[2];
        aD[0] = lowerlayer;
        aD[1] = background;
        LayerDrawable _highlightedDrawable = new LayerDrawable(aD);
        setBackgroundDrawable(_highlightedDrawable); // buttons need transparent backgrounds
      } else if (!enabled) {
        setColorFilter(null);
        setAlpha(_disabledAlpha);
      } else if (enabled && pressed){
        ScaleDrawable smaller = new ScaleDrawable(background, 0, 0.75f, 0.75f);
        setBackgroundDrawable(smaller.getDrawable());
      } else if(enabled){
        setBackgroundDrawable(background);  
        setColorFilter(null);
      }
      invalidateSelf();
      return super.onStateChange(states);
    }
}
}
Here's my xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff">
<ImageButton
    android:id="@+id/title"
    android:layout_width="250dp"
    android:layout_height="58dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_margin ="25dp"
    android:background="@drawable/skintonetitle" />
<custombuttons.CustomImageButton
    android:id="@+id/skina1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/title"
    android:layout_below="@+id/title"
    android:layout_marginTop="35dp"
    android:background="@drawable/test_circle"
    android:clickable="true"
    android:focusable="true" />
</RelativeLayout>
Something I've missed?
It extends from View, not button, so it's not clickable or focusable by default. Adjust with
android:clickable="true"
android:focusable="true"
in your XML.
You can also set these in the constructor of your View class if you want to do it in java:
setFocusable(true);
setClickable(true);
in my case I was using a custom view with a constraint layout as the root .and I was not getting click events on setOnClickListener of my custom view,it turns out that I needed to set android:clickable="false" in the root of my xml for the custom view.apparently , the click event is dispatched to the root of my custom view xml rather than to the custom view it self (i.e setOnClickListener of the custom view )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With