Add ?attr/selectableItemBackground to View and set Background Color

2.3k views Asked by At

I have a View that I created programmatically, and I want to have a ripple effect when I select it. I was able to get that working using ?attr/selectableItemBackground. However, I also want to set the background color of the View when I select it. I've tried setBackgroundResource(selectableAttr) and then setBackgroundColor(colorSelectBackground), but the color seems to overwrite the resource, so I only have one or the other. Here's my code:

int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = context.obtainStyledAttributes(attrs);
int backRes = typedArray.getResourceId(0, 0);

public void select() {
    view.setSelected(true);
    view.setBackgroundResource(backRes);
    view.setBackground(colorSelectBackground);
}

public void deselect() {
    view.setSelected(false);
    view.setBackground(colorSelectBackground);
}

Anyone know how I can use both ?attr/selectableItemBackground and also set a background color? Thanks!

EDIT: To clarify, the view in question isn't a button, it's a RelativeLayout.

UPDATE: I never really found a good solution for this. The closest I got was using View.setForeground() to a Drawable from the TypedArray, i.e.

view.setForeground(typedArray.getDrawable(0));

The main drawback to this is that it's only available on API 23+. Let me know if you come up with a better solution.

1

There are 1 answers

1
Ognian Gloushkov On

I'd recommend creating a custom View, where you can get the pressedColor, defaultColor and disabledColor from the xml.

The following code would work for a Material styled button:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
    ColorStateList colorStates = new ColorStateList(
            new int[][]{
                    new int[]{android.R.attr.state_pressed},
                    new int[]{}
            },
            new int[]{
                    pressedColor,
                    defaultColor});

    view.setBackgroundDrawable(isEnabled ? new RippleDrawable(colorStates, getBackground(), getBackground())
            : new ColorDrawable(disabledColor);
}
else
{
    StateListDrawable backgroundDrawable = new StateListDrawable();
    backgroundDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(isEnabled ?
            pressedColor : disbledColor));
    backgroundDrawable.addState(StateSet.WILD_CARD, new ColorDrawable(isEnabled ? defaultColor :
            disabledColor));
    view.setBackgroundDrawable(backgroundDrawable);
}