Use different icons with different Android SDK versions - android

I have icons for my Android menu. On Android 3+ I'm using a black ActionBar so the icons are white. However, on Android 2.x the menu is inherently white which means the icons are nearly invisible. How can I use different menu icons for different versions? I'm assuming I can do it using different drawable directories like res/drawable-mdpi-v11, but I'm wondering if there is another way so I don't have to create a bunch of different directories as I add versions or pixel densities.
EDIT: I put dark versions in res/drawable-mdpi and res/drawable-hdpi for use with Android 2.x and I put light versions in res/drawable-mdpi-v11 and res/drawable-hdpi-v11 for use with Android 3.x and higher, but my Android 2.1 (sdk 7) emulator is still showing the light version.
Any idea why?

You can Select a theme based on platform version, as outlined in the Styles and Themes dev guide. Define a style in your res/values/styles.xml like this:
<style name="ThemeSelector" parent="android:Theme.Light">
...
</style>
Then in a res/values-v11/ folder, select your theme (probably Holo, if you're dark)
<style name="ThemeSelector" parent="android:Theme.Holo">
...
</style>
Then add icons to that style. For instance, here's a snippet from the styles.xml file from the HoneycombGallery sample application.
<style name="AppTheme.Dark" parent="#android:style/Theme.Holo">
...
<item name="menuIconCamera">#drawable/ic_menu_camera_holo_dark</item>
<item name="menuIconToggle">#drawable/ic_menu_toggle_holo_dark</item>
<item name="menuIconShare">#drawable/ic_menu_share_holo_dark</item>
</style>
The bottom 3 elements are all icons in the drawable directories. You'll still need at least one folder per resolution-specific set of icons, but you can combine the light & dark icons into the same folder, but you won't have to have different folders of icons for each platform version. Also, you'll need to list them as references in the values/attrs.xml file, like this:
<resources>
<declare-styleable name="AppTheme">
<attr name="listDragShadowBackground" format="reference" />
<attr name="menuIconCamera" format="reference" />
<attr name="menuIconToggle" format="reference" />
<attr name="menuIconShare" format="reference" />
</declare-styleable>
</resources>
At which point you'll be able to refer to them within your layout XML using the "?attr/NameOfYourDrawable" dereference, like this:
<item android:id="#+id/menu_camera"
android:title="#string/camera"
android:icon="?attr/menuIconCamera"
android:showAsAction="ifRoom" />

Found on the android dev site: http://developer.android.com/guide/practices/ui_guidelines/icon_design_menu.html
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. Note that the grid below is not intended to be complete.
/res/drawable-hdpi (for Android 2.2 and below)
/res/drawable-hdpi-v# (for Android 2.3 and above)
Have you also tried testing this on a 2.1+ phone and not an emulator? If you don't have a phone, try creating another AVD? I'm afraid that you're going to need the separate folders.
Hopefully this helps.

Related

Customizing Support Action Bar / Android

I recently started Android programming, all is good and dandy, but I've came across a problem that I couldn't find an answer to, and I really diged hard for 4 days so far.
My app uses support action bar, and to be specific "android.support.v7.app.ActionBarActivity". Long story short, I couldn't handle most of the stuff applicable to an Action Bar to this support one.
My app uses this support action bar by default due to setting up my mini sdk version to 14.
I want to be able to build an action bar from scratch, and customize it, since the default action bar is not responsive to my customization in styles.xml, etc.
I don't mind using Holo theme library instead of AppCompat.
So the question here, how can use Action Bar instead of Support Action Bar?
How can I extend my java class to use that instead of the support one?
Because none of the online customizing solutions are applicable to the support action bar.
A bit foggy description so I apologize for that.
Create a new project, and select the minimum API level as 15. When you do this, the appcompat-v7 library will not be required for this project as it is for projects with minSdkversion < 15. In this project, the classes android.app.ActionBarActivity and android.app.ActionBar will be used by default, i.e. the native AOSP classes and not the ones from the support library.
The following will let you have an ActionBar with custom background color as you want it, on API level 8 and above.
STEP 1. In your res/values folder, define an XML file theme.xml and add the following to it:
<resources
xmlns:tools="http://schemas.android.com/tools">
<style name="DefaultActionBarTheme" parent="#style/Theme.AppCompat.Light">
<item name="android:actionBarStyle" tools:targetApi="11">#style/MyActionBar</item>
<item name="actionBarStyle">#style/MyActionBar</item>
<item name="android:actionBarSize" tools:targetApi="11">#dimen/action_bar_wrap_content</item>
<item name="actionBarSize">#dimen/action_bar_wrap_content</item>
</style>
<style name="MyActionBar" parent="#style/Widget.AppCompat.Light.ActionBar">
<item name="android:background" tools:targetApi="11">#color/actionbarbgcolor</item>
<item name="background">#color/actionbarbgcolor</item>
<item name="android:height" tools:targetApi="11">#dimen/action_bar_wrap_content</item>
<item name="height">#dimen/action_bar_wrap_content</item>
</style>
</resources>
In the same folder make another XML file colors.xml and add the following to it:
<resources>
<color
name="actionbarbgcolor">#00FF00
</color>
</resources>
and to the existing file dimens.xml, add the last line:
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!-- Optional, in case you wish to increase the default width of the Action Bar. -->
<dimen name="action_bar_wrap_content">55dp</dimen>
</resources>
In place of #00FF00 above, use the hex color code for the background color you wish to use in your ActionBar.
NOTE: The above will work assuming you are using the appcompat-v7 library. If not, then you'll have to use one of the Holo.Light themes instead of AppCompat.Light, and there will be other changes as well.
STEP 2. In your manifest file, you must add:
android:theme="#style/DefaultActionBarTheme"
to every <activity declaration if that Activity has the ActionBar.
Try this. It will work.
Zygotelnit answer works but you have to omit the ["tools:targetApi="11"] from item declaration otherwise it will give you an error for some reason.
On the other hand, I've found a much shorter and easier but not so optimized solution.While searching through the actionBar class and playing around here is the answer:
In your activity.java, go down to
protected void onCreate(Bundle savedInstanceState)
Anywhere appropriate in that method, write the following code:
ActionBar actionBar = getSupportActionBar();
actionBar.setBackgroundDrawable(new
ColorDrawable(Color.parseColor("#D62D20")));
You replace the color code by any color code of your choosing. It's obviously a hex color code.

Holo Theme and API 8

I have an app that must be supported from API 8+. But I also like to have my app the holo theme for(11+). I know it won't be supported as the min sdk is 8. So the only solution will be to create 2 separate apps one for 8-11 and one for 11+. Is there any better way to do this? So that I can reduce double maintenance.
There's no need to create two separate apps. You just need to create two definitions of theme for your app:
styles.xml in /res/values-v11 (Will be used only on API 11+)
<resources>
<style name="app_theme" parent="android:Theme.Holo.Light"/>
</resources>
styles.xml in /res/values
<resources>
<style name="app_theme" parent="android:Theme.Light"/>
</resources>
and then, apply it to your application in AndroidManifest.xml:
<application
...
android:theme="#style/app_theme"
>
...
</application>
This setup uses resource qualifiers. You can read more about them here.
You can try the HoloEverywhere library to use Holo theme on Android 2.1+. It also integrates well with ActionBarSherlock.

Multilanguage and multitheme at same time

I'm developing an app that has multilanguage support (using the /res/values-** way) with success. Then I want to use Holo and falling legacy devices (2.3.* for example) to use the default one (using the /res/values-v11 way).
So, I end up with a structure similar to this one (the one without language is EN, as default):
/res/values
/res/values-v11
/res/values-de
/res/values-de-v11
/res/values-es
/res/values-es-v11
... where in each one I have the following:
strings.xml
themes.xml
... where strings.xml is where the localised text are defined, and themes.xml has:
For non-v11 directories (legacy devices)
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="MyTheme" parent="#android:style/Theme">
<!-- Any customizations for your app running on pre-3.0 devices here -->
</style>
</resources>
For -v11 directories (+3.0 devices)
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="MyTheme" parent="#android:style/Theme.Holo">
<!-- Any customizations for your app running on devices with Theme.Holo here -->
</style>
</resources>
Remembering to add this attribute into the application tag on AndroidManifest.xml
android:theme ="#style/MyTheme"
This is working in all languages and all devices, current and legacy, with correct theme picking and everything. Tested in several physical devices.
So, the question:
Don't you think that this is heavily maintainable? I mean, then we have 2 string.xml files for every language which are exactly identical, but for every new text we have to fill it twice, increasing the risk of typos. The same happens if you have analytics.xml, styles.xml, ... inside
Having the language handling so nice in Android using strings.xml, is there any other workaround to have this working multitheme and multilanguage in a nicer way?
Thank you.
I'm not sure why do you need something like
values-de-v11
I would just use something like this:
values
values-de
values-fr
values-es
values-cat
...
And put inside every strings.xml file with the translation.
On the other hand you can also add the folders:
values
values-v11
And inside you can add your themes.
The folder values should have both the strings.xml for the default language (usually english) and the fallback theme file for devices without holo.
You can check all the possibilites in the documentation:
http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources

Difference between pre ICS and post ICS Holo theme related

I have a couple of app that were created with Android 1.6 and after. The problem is when I run these app on recent Android (device or simulator) like ICS, I don't have the Holo theme.
I know i can find a lot of thread on how to specify the theme but when I create a new app now, I have the new theme without any lines of code.
I don't want to have ICS theme on all android version, just ICS theme on ICS, like new holo buttons style on ICS and old grey style for older. Now I just have grey buttons for all versions.
I can create new empty projects and copy all my files into it but there must be a hidden value somewhere to chenge this.
In my manifest I have:
<uses-sdk android:minSdkVersion="3" />
<uses-sdk android:targetSdkVersion="14" />
What can be the difference between old and new created projects ?
What I'm understanding is that you want your app to switch between the legacy (classic) theme and the new Holo theme based on API version.
First, in your values (res/values) folder make a new xml. Call it styles.xml. It should contain these lines:
<resources>
<style name="AppTheme" parent="#android:style/Theme.Black"/>
</resources>
Then make a new folder in res called values-v11. In this new folder make another new xml. Also name it styles.xml This file should contain these lines:
<resources>
<style name="AppTheme" parent="#android:style/Theme.Holo"/>
</resources>
Then in your AndroidManifest.xml you Application node should contain this line:
android:theme="#style/AppTheme"
Now on devices with Honeycomb or higher you get the Holo theme and for everything else, you get the old classic theme. You can easily experiment with this to suit your needs - this is the general way to switch between themes based on API version.

where do I place themes.xml?

In what directory do I have to place my themes.xml in order that my android recognises the correct version?
I have two versions of themes.xml. One is used by tablets. And the other one shall be used for phones with large screens. I placed the one for tablets in the folder res\values-v11\themes.xml and the other one in res\values\themes.xml
Unfortunately someting doesn't work. I definied a textColor for textViews in each of the files with different colors, so that I can recognise the file which was chosen by the OS on different phones. It worked perfectly on a xoom tablet with android 3.2. On a galaxy s2 with 2.3.5 it doesn't work.
What am I missing?
Here are the styles I use:
Tablet:
<style name='MyTheme' parent='android:Theme.Holo.Light'>
<style name='MyAutoComplete.red' parent='#style/MyAutoComplete'>
<item name='textColor'>#color/red</item>
</style>
Non-Tablet:
<style name='MyTheme' parent='android:Theme.Light.NoTitleBar'>
<style name='MyAutoComplete.blue' parent='#style/MyAutoComplete'>
<item name='textColor'>#color/blue</item>
</style>
Since your requirement is to track OS version by textView's color.
I have following suggestion. (Colors are for example only, you can change yourself)
res/values -> Yellow Color // Phone using 2.3.* or before
res/values-v11 -> Red Color // Phone using 3.0 or later
res/values-xlarge -> Green Color // Tablet using 2.3.* or before
res/values-xlarge-v11 -> Blue Color // Tablet using 3.0 or later
So a Xoom should show Blue, a S2 (2.3.*) should show Yellow, a Galaxy nexus should show Red.
You need to create a theme in styles.xml and place it in res/values folder.
Put "Tablet" in res/values-xlarge and "Non-Tablet" in res/values
You need to have two seperate xml files for the two themes to able to run the theme in the two seperate devices
Place both in resource :)
Hope it helps

Categories

Resources