Asked  7 Months ago    Answers:  5   Viewed   30 times

In the Android SDK documentation, all of the examples used with the @drawable/my_image xml syntax directly address images that are stored in the res/drawable directory in my project.

I am wondering if it is explicitly not okay to create a sub directory within the drawable directory.

For example, if I had the following directory layout:

res/drawable
-- sandwiches
  -- tunaOnRye.png
  -- hamAndSwiss.png
-- drinks
  -- coldOne.png
  -- hotTea.png

Could I reference the image of a tuna salad sandwich as @drawable/sandwiches/tunaOnRye

Or do I have to keep the hierarchy flat in the drawable directory.

 Answers

22

No, the resources mechanism doesn't support subfolders in the drawable directory, so yes - you need to keep that hierarchy flat.

The directory layout you showed would result in none of the images being available.

From my own experiments it seems that having a subfolder with any items in it, within the res/drawable folder, will cause the resource compiler to fail -- preventing the R.java file from being generated correctly.

Tuesday, June 1, 2021
 
Deyson
answered 7 Months ago
65

You CAN do this with gradle. I've made a demo project showing how.

The trick is to use gradle's ability to merge multiple resource folders, and set the res folder as well as the nested subfolders in the sourceSets block.

The quirk is that you can't declare a container resource folder before you declare that folder's child resource folders.

Below is the sourceSets block from the build.gradle file from the demo. Notice that the subfolders are declared first.

sourceSets {
    main {
        res.srcDirs =
        [
                'src/main/res/layouts/layouts_category2',
                'src/main/res/layouts',
                'src/main/res'
        ]
    }
}

nested resources picture

Also, the direct parent of your actual resource files (pngs, xml layouts, etc..) does still need to correspond with the specification.

Tuesday, June 1, 2021
 
millenomi
answered 7 Months ago
18

You have some options to handle this deprecation the right (and future proof) way, depending on which kind of drawable you are loading:


A) drawables with theme attributes

ContextCompat.getDrawable(getActivity(), R.drawable.name);

You'll obtain a styled Drawable as your Activity theme instructs. This is probably what you need.


B) drawables without theme attributes

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

You'll get your unstyled drawable the old way. Please note: ResourcesCompat.getDrawable() is not deprecated!


EXTRA) drawables with theme attributes from another theme

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
Tuesday, June 1, 2021
 
Avicinnian
answered 7 Months ago
41

Yes it looks first in the drawable-en, then drawable-hdpi because language qualifier has higher precedence. If value was still not found drawable directory is searched. It is in accordance with: How Android Finds the Best-matching Resource

If drawable-en contains matching resource then drawable-hdpi and drawable would be eliminated based on step 4 of the algorithm.

Friday, August 20, 2021
 
Gopi
answered 4 Months ago
17

How do I access ic_menu_login then?

Copy it into your application. You can find all of them in your SDK installation, specifically in $ANDROID_HOME/platforms/$API/data/res/, where $ANDROID_HOME is wherever you installed the SDK and $API is some Android level (e.g., android-2.1).

Saturday, October 16, 2021
 
dkcwd
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share