51

android.R.attr.selectableItemBackground exists, but how do I add it programatically to an ImageButton?

Also, how would I go about finding the answer in the documentation? It's mentioned here, but I don't see any explanation of how it's actually used. Actually, I rarely seem to find the documentation useful, but I'm hoping that's my fault and not that of the documentation.

Mogsdad
  • 40,814
  • 19
  • 140
  • 246
abc32112
  • 2,357
  • 8
  • 34
  • 52

4 Answers4

54

Here is an example using answer here: How to get the attr reference in code?

    // Create an array of the attributes we want to resolve
    // using values from a theme
    // android.R.attr.selectableItemBackground requires API LEVEL 11
    int[] attrs = new int[] { android.R.attr.selectableItemBackground /* index 0 */};

    // Obtain the styled attributes. 'themedContext' is a context with a
    // theme, typically the current Activity (i.e. 'this')
    TypedArray ta = obtainStyledAttributes(attrs);

    // Now get the value of the 'listItemBackground' attribute that was
    // set in the theme used in 'themedContext'. The parameter is the index
    // of the attribute in the 'attrs' array. The returned Drawable
    // is what you are after
    Drawable drawableFromTheme = ta.getDrawable(0 /* index */);

    // Finally free resources used by TypedArray
    ta.recycle();

    // setBackground(Drawable) requires API LEVEL 16, 
    // otherwise you have to use deprecated setBackgroundDrawable(Drawable) method. 
    imageButton.setBackground(drawableFromTheme);
    // imageButton.setBackgroundDrawable(drawableFromTheme);
Community
  • 1
  • 1
Timuçin
  • 4,597
  • 3
  • 23
  • 33
  • 12
    This did not work, at least on Lollipop with AppCompat. However, [this did.](http://stackoverflow.com/a/28087443/1489860) – Jeffrey Mixon Feb 14 '15 at 04:16
  • Code works fine for me on Lollipop with AppCompat (May 2017) - only difference was I used `View.setForeground(Drawable)` instead of `setBackground()` – Richard Le Mesurier May 26 '17 at 15:47
51

If you are using AppCompat you could use following code:

int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = context.obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
view.setBackgroundResource(backgroundResource);
typedArray.recycle();
James McCracken
  • 14,210
  • 4
  • 49
  • 59
Andrey T
  • 1,958
  • 18
  • 18
9

This works for me with my TextView:

// Get selectable background
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.selectableItemBackground, typedValue, true);

clickableTextView.setClickable(true);
clickableTextView.setBackgroundResource(typedValue.resourceId);

Because I use AppCompat library, I use R.attr.selectableItemBackground not android.R.attr.selectableItemBackground.

I think typedValue.resourceId holds all drawables from selectableItemBackground than using TypeArray#getResourceId(index, defValue) or TypeArray#getDrawable(index) which are retrieve only a drawable at the given index.

maohieng
  • 1,336
  • 16
  • 25
4

Try this method:

public Drawable getDrawableFromAttrRes(int attrRes, Context context) {
    TypedArray a = context.obtainStyledAttributes(new int[] {attrRes});
    try {
        return a.getDrawable(0);
    } finally {
        a.recycle();
    }
}

// Then just call it like this:

getDrawableFromAttrRes(R.attr.selectableItemBackground, context)

// Example
ViewCompat.setBackground(view,getDrawableFromAttrRes(R.attr.selectableItemBackground, context))
Sergio Serra
  • 1,429
  • 2
  • 17
  • 24
  • 1
    Sometimes Android Studio will warn about using `R.attr.selectableItemBackground`, so it may be safer to replace it with `android.R.attr.selectableItemBackground` – Mr-IDE Apr 22 '19 at 18:11