2

This answer helped a bit, but doesn't quite cover my issue.

Here is what my XML looks like:

<android.support.v7.widget.CardView
    ... other attributes...
    android:foreground="?android:attr/selectableItemBackground"
    >

The issue is that I would like to be able to resolve that attr in code. Here is what I have so far:

val typedValue = TypedValue()
context.theme.resolveAttribute(R.attr.selectableItemBackground, typedValue, true)
typedValue.string // "res/drawable/item_background_material.xml"
typedValue.type   // 3 (string)
typedValue.data   // 656

I could use the linked answer, I suppose, to directly resolve R.drawable.item_background_material, but the whole point of using ?android:attr/... is that I don't know where that attr points. How do I make use of the information contained in the TypedValue object to resolve the drawable reference?

Btw, I have tried

val drawableRes = string.substring(string.lastIndexOf("/") + 1, string.indexOf(".xml")) // gross, but it's just a proof of concept
val drawable = resources.getIdentifier(drawableRes, "drawable", context.packageName)

but the result is always 0.

AutonomousApps
  • 4,229
  • 4
  • 32
  • 42
  • 1
    Look at the [`resourceId` field](https://developer.android.com/reference/android/util/TypedValue.html#resourceId). That is, `typedValue.resourceId`. – Mike M. Apr 09 '18 at 19:24
  • 1
    a-ha! that totally worked. `val drawable = context.getDrawable(typedValue.resourceId)`. If you submit that as an answer, I will accept. – AutonomousApps Apr 09 '18 at 19:28

1 Answers1

1

That resource identifier will be in the resourceId field. That is, in your example, typedValue.resourceId.

For anyone using Kotlin, here's a pretty neat way to implement that:

foreground = with(TypedValue()) {
    context.theme.resolveAttribute(R.attr.selectableItemBackground, this, true)
    ContextCompat.getDrawable(context, resourceId)
}
AutonomousApps
  • 4,229
  • 4
  • 32
  • 42
Mike M.
  • 38,532
  • 8
  • 99
  • 95