Android: drawable resource from earlier API level - android

Is there a way in Android to use a drawable resource from an earlier Android version / API level then the one of the current project? More specifically, is there a way to access it in the project without putting it into the drawable resource folder manually?
In my specific case, I would like to use android.R.drawable.btn_check_buttonless_on from Android 2.2 in a project that uses Android 4.0. Because in 4.0 it's not used anymore, I obviously cannot just reference it like
myMenuItem.setIcon(android.R.drawable.btn_check_buttonless_on);
Is there another way to include the drawable resources of earlier versions?

I found this:
https://androidcookbook.com/Recipe.seam;jsessionid=0443546CEE776318BF6D21552A9D1864?recipeId=3823
many (most?) of the resources are, for one reason or another, marked as non-public; presumably these are intended only for use by particular components. The non-public give a diagnostic that the "Resource is not public". You can still use the non-public one,s but you have to extract the image drawables and copy them into your project.
I'll try it as well.
Edit:
it worked for me:
go to your android SDK/platforms/android-19/
extract android.jar
go to android/res/
there you have all the drawables you want to use (inside the drawable folders).
You have to copy all the .png file into your project.

Related

Why does Android Studio create the ic_launcher_foreground in res/drawable-v24 and the ic_launcher_background.xml in res/drawable?

Firstly
I noticed when creating a new project in Android Studio it generates drawable-v24 folder with ic_launcher_foreground.xml icon.
And my question is:
If vector drawables were introduced before v24 then why does it put the vector asset in drawable-v24 and not in drawable-v21 folder?
Secondly
Another generated asset is ic_launcher_background.xml which is created in res/drawable folder and was later referenced from mipmap-anydpi-v26/ic_launcher.xml.
If it is only used in API v26+ (adaptive icons) then why was it created in res/drawable folder and not in res/drawable-v24 or in res/drawable-v26? Is it due to some nature of mipmap folders?
The VectorDrawable feature is somewhat integrated in API-24 though it was introduced from API-21. I think Google's developers think API-24+ is ideal or stable for adaptive icons.
For example, Nick Butcher (Android designer + developer # Google) said in his article: Using vector assets in Android apps (Dec 11, 2018),
Both nonZero and evenOdd path fillTypes —the two common ways of defining the inside of a shape, often used in SVGs (evenOdd added to platform impl in API 24)
Gradient & ColorStateList fills/strokes (added to platform impl in API 24)
And about ic_launcher_background, it is referenced only from mipmap-anydpi-v26/ic_launcher.xml and mipmap-anydpi-v26/ic_launcher_round.xml. I think it is just that there is no need to prevent from referencing it directly (It has already prevented by placing ic_launcher.xml and ic_launcher_round.xml in mipmap-anydpi-v26 folder). There should be not so far more, deep meanings.
A codelab answers your questions.
Depending on the min SDK of your app, you may notice that the foreground asset is located in the drawable-v24 folder, while the background asset is in the drawable folder. The reason is because the foreground asset contains a gradient, which was available starting in the Android 7.0 release (also known as API version 24, hence the -v24 resource qualifier). The background asset doesn't contain a gradient, so that can go in the base drawable folder.
As a side note, though we generally don't use ic_launcher_background.xml for any purpose other than the app icon, it is just a vector drawable and its usage is not limited.

How to make an application's vector drawable override a library's vector drawable?

I have a library project and an application project. Beside other things the libary project contains some png and some vector drawables. Now I can easily overwrite a png drawable in the application project by giving it the same name and it will be displayed correctly. This does not work with vector drawables, though: The app always shows the vector drawables defined in the library, both on Android 4 and 5. The app would never show the application project's vector drawables.
Google claims an application's resources always have priority over a library's resources:
Since the tools merge the resources of a library module with those of a dependent application module, a given resource ID might be defined in both modules. In this case, the tools select the resource from the application, or the library with highest priority, and discard the other resource. As you develop your applications, be aware that common resource IDs are likely to be defined in more than one project and will be merged, with the resource from the application or highest-priority library taking precedence.
But as I said, in case of vector drawables, for some reason, it's the other way round. Any idea what I can do to make sure the vector drawables are overridden just like normal drawables and other resources are?
UPDATE: Resolved in support library v23.2! Nothing to do now :)
When the library project is built, the VectorDrawable creates PNG files for each density and places the original VectorDrawable in drawable-anydpi-v21.
If you place your VectorDrawable in drawable-anydpi-v21 in your app, then it will override the drawable from your library project. This seems like a bug and a new issue should be created (if one doesn't already exist).
NOTE: this will not replace the generated PNG files from the library. You will need to add those to your app as well to override them.
Based on the "NOTE" in Jared Rummler's answer and since this won't fit in a comment I'll post a little tutorial here for people who have trouble finding the generated PNG files:
You can find the folders with the required files inside build/intermediates/res/merged/debug or, if you are using product flavors build/intermediates/res/merged/<flavor>/debug. Now the least difficult way of copying the PNG files to the app would be to fully copy their folders, which are:
drawable-ldpi-v4
drawable-mdpi-v4
drawable-hdpi-v4
drawable-xhdpi-v4
drawable-xxhdpi-v4
drawable-xxxhdpi-v4
As a last and tedious step you should remove all files inside you don't need, i.e. those that aren't generated from your vector drawables. This is done easiest if you are using a VCS by adding only the PNGs you need. This places all redundant files under Unversioned Files.
And there you go, together with drawable-anydpi-v21 there are now 7 additional folders just because of this stupid bug :(
UPDATE: Resolved in support library v23.2! As of today, there is finally no need to do any of the above. Just make sure to use app:srcCompat instead of android:src everywhere.

Android app crashes with Drawable resource as background

This is my first android project so please bear with me. My app is crashing whenever i change a layout's background, I noticed that the layout won't crash if the background drawable does not include a (v21) next to it. For example setting the background as #drawable/gradient_bg it works fine, on the other hand, #drawable/gradient_bg_purple it crashes the application when the layout is loaded.
What does the (v21) mean ? I'm guessing it has to do with an android API v? Does that mean I should have a different file for all versions ? :/
I'm testing on an HTC - Android V-4.1.2 - HTC SDk level - 5.26
Thanks
v21 means that the resource will be used/available on Android versions 21 and up. So in your case, that resource will be non existent for any Android versions lower than that.
Update
You should take those drawables out of drawable-v21 and place them in the appropriate folder based on your desired density. For example, place it in drawable-mdpi, drawable-hdpi, etc.
v21 represents the minimum API level that will use this drawable.
You are running Android 4.1.2, which uses API v16.
Apparently, you created a drawable-v21 directory in your resources (res) directory.
Please check if that's the case and move the drawable to the drawable directory.
If that is indeed that case, it may be because Android Studio suggested this change and you're using features that are specific to v21 API.
We can provide more help if you show us this gradient_bg_purple.xml file.

Can't use android spinner drawable?

I'm trying to use one of Android's spinner drawables (spinner_black_16, spinner_black_20, spinner_black_48, or spinner_black_76) as demonstrated on this page. My project is using SDK 2.1, so I updated it to 2.2 as that page states is the SDK version where these are included. Unfortunately, none of the android.R.drawable.spinner_black_xx appear to be defined.
Are these drawables not available for developer usage? The only other way I seem to be able to access them is via the following convoluted method:
final Drawable spinner = new ProgressBar(context).getIndeterminateDrawable();
Unfortunately, that provides me the white spinner, not the black one.
The best way to access those drawables is to copy them from your SDK directory into your project and then access them like any other resources.
The drawables are located in $ANDROID_SDK_DIR/platforms/android-*/data/res/drawable-*/. You can download and select the version of the OS that you'd like to pull drawables from. API level 7/OS version 2.1 has the full complement:
platforms/android-7/data/res/drawable-mdpi/spinner_black_16.png
platforms/android-7/data/res/drawable-mdpi/spinner_black_20.png
platforms/android-7/data/res/drawable-mdpi/spinner_black_48.png
platforms/android-7/data/res/drawable-mdpi/spinner_black_76.png
platforms/android-7/data/res/drawable-hdpi/spinner_black_16.png
platforms/android-7/data/res/drawable-hdpi/spinner_black_20.png
platforms/android-7/data/res/drawable-hdpi/spinner_black_48.png
platforms/android-7/data/res/drawable-hdpi/spinner_black_76.png
Though it doesn't currently, Android's official "Icon Design Guidelines" used to explicitly address this situation and recommend copying:
Because resources can change between platform versions, you should not reference built-in icons using the Android platform resource IDs (i.e. status bar icons under android.R.drawable). If you want to use any icons or other internal drawable resources, you should store a local copy of those icons or drawables in your application resources, then reference the local copy from your application code. In that way, you can maintain control over the appearance of your icons, even if the system's copy changes.

How to use default Android drawables

What is the best approach when using default Android drawables? Should I use android.R.drawable or should I copy the drawables in my project and use R.drawable?
Is there any risk, that in a newer version of Android, some of the default drawables are removed or resized? Or, affect in some negative way, the look of my app? Also, which of the drawables in the Android source code are considered "stable" and should be relied on?
I'd rather not copy the drawables because I think that the look of the app should be consistent with the Android version used. So, for example, for version 1.6 it should use the default Android bitmaps for version 1.6.
Java Usage example: myMenuItem.setIcon(android.R.drawable.ic_menu_save);
Resource Usage example: android:icon="#android:drawable/ic_menu_save"
As far as i remember, the documentation advises against using the menu icons from android.R.drawable directly and recommends copying them to your drawables folder. The main reason is that those icons and names can be subject to change and may not be available in future releases.
Warning: Because these resources can change between platform versions, you should not reference these icons using the Android platform resource IDs (i.e. menu icons under android.R.drawable). If you want to use any icons or other internal drawable resources, you should store a local copy of those icons or drawables in your application resources, then reference the local copy from your application code. In that way, you can maintain control over the appearance of your icons, even if the system's copy changes.
from: http://developer.android.com/guide/practices/ui_guidelines/icon_design_menu.html
If you read through any of the discussions on the android development group you will see that they discourage the use of anything that isn't in the public SDK because the rest is subject to extensive change.
Better you copy and move them to your own resources. Some resources might not be available on previous Android versions. Here is a link with all drawables available on each Android version thanks to #fiXedd
To use the default android drawable resource, no need copy anything..
you can just import it first with..
import android.R;
but i will make your own resources will have an error if you want to use it.
The error will be something like:
R. cannot be resolved
So, I prefer not to import android.R but import *my.own.package*.R;
then when I can normally use my own resource with R.drawable.*something* without error,
and put android.R.*something_default* to use the default android resources.
Better to use android.R.drawable because it is public and documented.

Categories

Resources