Platform Resource Aliases
One of the reasons why I keep close tabs on Stack Overflow is that, every now and then, I’m reminded of a technique that I should be promoting more.
Today’s example of this comes from this question,
where a developer inheriting an existing Android Studio project questioned
why the project had a
res/values/drawables.xml file that contains
a bunch of
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <item name="ic_menu_camera" type="drawable">@android:drawable/ic_menu_camera</item> <item name="ic_menu_gallery" type="drawable">@android:drawable/ic_menu_gallery</item> <item name="ic_menu_slideshow" type="drawable">@android:drawable/ic_menu_slideshow</item> <item name="ic_menu_manage" type="drawable">@android:drawable/ic_menu_manage</item> <item name="ic_menu_share" type="drawable">@android:drawable/ic_menu_share</item> <item name="ic_menu_send" type="drawable">@android:drawable/ic_menu_send</item> </resources>
What the original developer did was set up project aliases for platform resources.
There are lots of resources available in the Android SDK. You are welcome to
refer to them directly if you want, such as
However, platform resources have two key problems:
They tend to be very specific.
android.R.color.blackis a color resource that resolves to black. It should always be black.
They might vary by Android version or even device manufacturer build. Some manufacturer, or even Google itself, might decide that orange is the new black and have
android.R.color.blackresolve to some shade of orange.
Ideally, you add a bit of indirection here, so that all of your Java code and other resources that today might use platform resources could switch tomorrow to some other implementation of those resources, without having to change all of the references to the resources.
Sometimes, we do this via styles and themes. However, that gets confusing, can be overkill, and does not necessarily cover all scenarios.
Resource aliases are another approach, the one taken by the original developer
of the code from the Stack Overflow question.
<item> elements, with
type pointing to the type of resource, gives us indirection. With the
above XML in a project, the project code and other resources can refer
R.drawable.ic_menu_share and such. Right now, the implementations of
those drawables happen to be platform resources, by means of the
elements. However, later on, you could get rid of the
<item> elements and
add custom drawables as replacements. Nothing that refers to the resource
needs to change, courtesy of the indirection.
Even in cases where you do not think that you will need to switch to a
custom resource, using this sort of indirection technique lets you
use logical resource names (e.g.,
R.color.divider instead of
android.R.color.black, to make it easier for you to switch to
android.R.color.holo_orange_dark later on without other code changes).
Again, styles and themes may supplant the need
for a lot of these aliases, but not everything belongs in a style resource.