23

I defined theme and style inside my app. icons (drawable) are defined using reference in style file as

<attr name="myicon" format="reference" />

and style as

<style name="CustomTheme" parent="android:Theme.Holo">
    <item name="myicon">@drawable/ajout_produit_light</item>

I need to retrieve the drawable programmatically to use the good image in a dialogfragment. If I make like

mydialog.setIcon(R.style.myicon);

I get an id equals to 0, so no image

I tried to use something like

int[] attrs = new int[] { R.drawable.myicon};
TypedArray ta = getActivity().getApplication().getTheme().obtainStyledAttributes(attrs);
Drawable mydrawable = ta.getDrawable(0);
mTxtTitre.setCompoundDrawables(mydrawable, null, null, null);

I tried different things like that but result is always 0 or null :-/

How I can I do this ?

arnouf
  • 790
  • 2
  • 7
  • 16

4 Answers4

22

I found the solution on Access resource defined in theme and attrs.xml android

TypedArray a = getTheme().obtainStyledAttributes(R.style.AppTheme, new int[] {R.attr.homeIcon});     
int attributeResourceId = a.getResourceId(0, 0);
Drawable drawable = getResources().getDrawable(attributeResourceId);
Community
  • 1
  • 1
arnouf
  • 790
  • 2
  • 7
  • 16
  • 9
    Don't forget to call a.recycle – Cheok Yan Cheng Mar 15 '16 at 17:07
  • 3
    For anyone else that was wondering: `a.recycle()` will signal that the allocated memory is no longer in use and the data associated with `a` can be returned to the memory pool immediately instead of waiting for garbage collection. As answered [here](http://stackoverflow.com/questions/7252839/what-is-the-use-of-recycle-method-in-typedarray) – Prof Mar 04 '17 at 23:44
20

Kotlin solution:

val typedValue = TypedValue()
context.theme.resolveAttribute(R.attr.yourAttr, typedValue, true)
val imageResId = typedValue.resourceId
val drawable = ContextCompat.getDrawable(context, imageResId) ?: throw IllegalArgumentException("Cannot load drawable $imageResId")
wbk727
  • 8,017
  • 12
  • 61
  • 125
Sevastyan Savanyuk
  • 5,797
  • 4
  • 22
  • 34
2

With the assumption your context (activity) is themed the way you want it, you can use resolveAttribute on the theme:

TypedValue themedValue = new TypedValue();
this.getTheme().resolveAttribute(R.attr.your_attribute, themedValue, true);
myView.setBackgroundResource(themedValue.resourceId);

So in your case it would look something like this:

TypedValue themedValue = new TypedValue();
this.getTheme().resolveAttribute(R.attr.myicon, themedValue, true);
Drawable mydrawable = AppCompatResources.getDrawable(this, themedValue.resourceId);
mTxtTitre.setCompoundDrawables(mydrawable, null, null, null);

In the examples this would be your activity. If you're not in an activity get a valid context.

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
-1

It would seem as though you are trying to set the icon of your myDialog using a resource and are trying to access it through R.style but your other code segment leads me to believe that you have the resource located in R.drawable

With that in mind you should be able to get the effect you want with myDialog.setIcon(R.drawable.myicon);

Jay Snayder
  • 4,298
  • 4
  • 27
  • 53