Android Tutorial Theme based on version Tutorial

What is this?
As the title suggests, this tutorial shows you how to select an android theme based on what version of Android your app is run on.

Why do I need this?
You don't, but after reading this tutorial you may think it is a useful technique that you wasn't previously aware of.

How could I use it?
There are many ways this can be used. For this tutorial I will use, what I believe will be the most common case study. Creating transparent activities whilst allowing the use of Holo based themes when available.

The problem
We want to create a transparent activity in our app but we also want our app to use a Holo theme when run on HoneyComb +. An example for a use of a transparent activity is to add a panel and some other views to create the effect of a 'popup window'.

Using the manifest editor, we can utilize the Holo dark theme simply by setting the targetSDK to 11 or higher or use the Light theme by setting a theme like this
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

Many of us will have followed this advice to create said transparent activity
http://www.b4x.com/forum/basic4android-updates-questions/14824-hiding-activity.html#post84047

BUT, there is a problem. Theme.Translucent.NoTitleBar does NOT utilize the nice new Holo theme. So your app would use Holo.Light, but your transparent activity would use the older default theme. This will look very unprofessional.

The Holo themes' Transparent effect can be gained by setting your application theme to
B4X:
@android:style/Theme.Holo.Light.Panel

But again, this has a problem. Run this on a device operating on an Android version less than HoneyComb (i.e. gingerbread) and you get an error as the theme simply doesn't exist.

So how do we stitch the 2 together? By setting the theme based on the version of Android in use. This does required creating some xml, but it's not too scary.

Here's what we do

After you have created your b4a project, open the projects' folder and navigate to the \res\ folder. within res create 2 new folders 'values' and 'values-v11'. Inside each of these folders we need a 'theme.xml' file. So we end up with

B4X:
\res\values\theme.xml
\res\values-v11\theme.xml

Anything added to the theme.xml in the values folder will be used as default. Anything added to the theme.xml in the values-v11 will be use when android v11 (honeycomb) or above is in use.

OK, what to put in them? essentially we are going to create a custom theme, so we need to give it a name. For this tutorial, we will call it 'MyThemeTransparent'. We need to add this text to the files

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style 
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style 
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

These files then need to be made read only!

Then in the b4a manifest editor, we use our custom theme like this:
B4X:
SetActivityAttribute(PopupWindow, android:theme, "@style/MyThemeTransparent")

PopupWindow being an activity we have created in b4a.

You may need to clean you b4a project for the theme resources to be recognized.

Advanced:
We can create more variants of our custom theme. Here is an example.

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style 
        name="MyTheme" parent="android:style/Theme.Light">
    </style>

    <style 
        name="MyThemeNoTitle" parent="android:style/Theme.Light.NoTitleBar">
    </style>

    <style 
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style 
        name="MyTheme" parent="@android:style/Theme.Holo.Light">
    </style>

    <style 
        name="MyThemeNoTitle" parent="@android:style/Theme.Holo.Light.NoActionBar">
    </style>

    <style 
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

This creates 3 variants.

MyTheme - A simple base theme that uses 'Theme.Light' on older versions of android and 'Theme.Holo.light' when available.

MyThemeNoTitle - As MyTheme but hides the titlebar (or ActionBar as it is now known)

MyThemeTransparent - Explained in tutorial above.

With this setup, i can set the base theme for the app using this in the manifest editor

B4X:
SetApplicationAttribute(android:theme, "@style/MyTheme")

Then use the other variants as explained above.

Hope this help some folks to make their apps look pretty.

Demo Project Below
This is a very simple demo to show you how things should look and feel after following this tutorial.
Hope it helps.

View attachment VersionThemeDemo.zip
 
Last edited:

barx

Well-Known Member
Licensed User
Longtime User
Thank you. This is extremely useful (i was waiting for this!).
Is it possible to have a different theme for certain activities?

Yes, that is exactly what we are doing when we use

B4X:
SetActivityAttribute(PopupWindow, android:theme, @style/MyThemeTransparent)

to set the activity as transparent, it uses a transparent theme ;)

PopupWindow - the activity to apply the theme to

android:theme - tell the system we are setting the theme.

@style/MyThemeTransparent - is the theme we are selecting.
 

barx

Well-Known Member
Licensed User
Longtime User
Added a simple demo project to original post.
 

LucaMs

Expert
Licensed User
Longtime User
What is this?
As the title suggests, this tutorial shows you how to select an android theme based on what version of Android your app is run on.

Why do I need this?
You don't, but after reading this tutorial you may think it is a useful technique that you wasn't previously aware of.

How could I use it?
There are many ways this can be used. For this tutorial I will use, what I believe will be the most common case study. Creating transparent activities whilst allowing the use of Holo based themes when available.

The problem
We want to create a transparent activity in our app but we also want our app to use a Holo theme when run on HoneyComb +. An example for a use of a transparent activity is to add a panel and some other views to create the effect of a 'popup window'.

Using the manifest editor, we can utilize the Holo dark theme simply by setting the targetSDK to 11 or higher or use the Light theme by setting a theme like this
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

Many of us will have followed this advice to create said transparent activity
http://www.b4x.com/forum/basic4android-updates-questions/14824-hiding-activity.html#post84047

BUT, there is a problem. Theme.Translucent.NoTitleBar does NOT utilize the nice new Holo theme. So your app would use Holo.Light, but your transparent activity would use the older default theme. This will look very unprofessional.

The Holo themes' Transparent effect can be gained by setting your application theme to
B4X:
@android:style/Theme.Holo.Light.Panel

But again, this has a problem. Run this on a device operating on an Android version less than HoneyComb (i.e. gingerbread) and you get an error as the theme simply doesn't exist.

So how do we stitch the 2 together? By setting the theme based on the version of Android in use. This does required creating some xml, but it's not too scary.

Here's what we do

After you have created your b4a project, open the projects' folder and navigate to the \res\ folder. within res create 2 new folders 'values' and 'values-v11'. Inside each of these folders we need a 'theme.xml' file. So we end up with

B4X:
\res\values\theme.xml
\res\values-v11\theme.xml

Anything added to the theme.xml in the values folder will be used as default. Anything added to the theme.xml in the values-v11 will be use when android v11 (honeycomb) or above is in use.

OK, what to put in them? essentially we are going to create a custom theme, so we need to give it a name. For this tutorial, we will call it 'MyThemeTransparent'. We need to add this text to the files

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

These files then need to be made read only!

Then in the b4a manifest editor, we use our custom theme like this:
B4X:
SetActivityAttribute(PopupWindow, android:theme, "@style/MyThemeTransparent")

PopupWindow being an activity we have created in b4a.

You may need to clean you b4a project for the theme resources to be recognized.

Advanced:
We can create more variants of our custom theme. Here is an example.

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyTheme" parent="android:style/Theme.Light">
    </style>

    <style
        name="MyThemeNoTitle" parent="android:style/Theme.Light.NoTitleBar">
    </style>

    <style
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyTheme" parent="@android:style/Theme.Holo.Light">
    </style>

    <style
        name="MyThemeNoTitle" parent="@android:style/Theme.Holo.Light.NoActionBar">
    </style>

    <style
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

This creates 3 variants.

MyTheme - A simple base theme that uses 'Theme.Light' on older versions of android and 'Theme.Holo.light' when available.

MyThemeNoTitle - As MyTheme but hides the titlebar (or ActionBar as it is now known)

MyThemeTransparent - Explained in tutorial above.

With this setup, i can set the base theme for the app using this in the manifest editor

B4X:
SetApplicationAttribute(android:theme, "@style/MyTheme")

Then use the other variants as explained above.

Hope this help some folks to make their apps look pretty.

Demo Project Below
This is a very simple demo to show you how things should look and feel after following this tutorial.
Hope it helps.

View attachment 16609

What is this?
As the title suggests, this tutorial shows you how to select an android theme based on what version of Android your app is run on.

Why do I need this?
You don't, but after reading this tutorial you may think it is a useful technique that you wasn't previously aware of.

How could I use it?
There are many ways this can be used. For this tutorial I will use, what I believe will be the most common case study. Creating transparent activities whilst allowing the use of Holo based themes when available.

The problem
We want to create a transparent activity in our app but we also want our app to use a Holo theme when run on HoneyComb +. An example for a use of a transparent activity is to add a panel and some other views to create the effect of a 'popup window'.

Using the manifest editor, we can utilize the Holo dark theme simply by setting the targetSDK to 11 or higher or use the Light theme by setting a theme like this
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

Many of us will have followed this advice to create said transparent activity
http://www.b4x.com/forum/basic4android-updates-questions/14824-hiding-activity.html#post84047

BUT, there is a problem. Theme.Translucent.NoTitleBar does NOT utilize the nice new Holo theme. So your app would use Holo.Light, but your transparent activity would use the older default theme. This will look very unprofessional.

The Holo themes' Transparent effect can be gained by setting your application theme to
B4X:
@android:style/Theme.Holo.Light.Panel

But again, this has a problem. Run this on a device operating on an Android version less than HoneyComb (i.e. gingerbread) and you get an error as the theme simply doesn't exist.

So how do we stitch the 2 together? By setting the theme based on the version of Android in use. This does required creating some xml, but it's not too scary.

Here's what we do

After you have created your b4a project, open the projects' folder and navigate to the \res\ folder. within res create 2 new folders 'values' and 'values-v11'. Inside each of these folders we need a 'theme.xml' file. So we end up with

B4X:
\res\values\theme.xml
\res\values-v11\theme.xml

Anything added to the theme.xml in the values folder will be used as default. Anything added to the theme.xml in the values-v11 will be use when android v11 (honeycomb) or above is in use.

OK, what to put in them? essentially we are going to create a custom theme, so we need to give it a name. For this tutorial, we will call it 'MyThemeTransparent'. We need to add this text to the files

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

These files then need to be made read only!

Then in the b4a manifest editor, we use our custom theme like this:
B4X:
SetActivityAttribute(PopupWindow, android:theme, "@style/MyThemeTransparent")

PopupWindow being an activity we have created in b4a.

You may need to clean you b4a project for the theme resources to be recognized.

Advanced:
We can create more variants of our custom theme. Here is an example.

\res\values\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyTheme" parent="android:style/Theme.Light">
    </style>

    <style
        name="MyThemeNoTitle" parent="android:style/Theme.Light.NoTitleBar">
    </style>

    <style
        name="MyThemeTransparent" parent="android:style/Theme.Translucent.NoTitleBar">
    </style>
</resources>

\res\values-v11\theme.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style
        name="MyTheme" parent="@android:style/Theme.Holo.Light">
    </style>

    <style
        name="MyThemeNoTitle" parent="@android:style/Theme.Holo.Light.NoActionBar">
    </style>

    <style
        name="MyThemeTransparent" parent="@android:style/Theme.Holo.Light.Panel">
    </style>
</resources>

This creates 3 variants.

MyTheme - A simple base theme that uses 'Theme.Light' on older versions of android and 'Theme.Holo.light' when available.

MyThemeNoTitle - As MyTheme but hides the titlebar (or ActionBar as it is now known)

MyThemeTransparent - Explained in tutorial above.

With this setup, i can set the base theme for the app using this in the manifest editor

B4X:
SetApplicationAttribute(android:theme, "@style/MyTheme")

Then use the other variants as explained above.

Hope this help some folks to make their apps look pretty.

Demo Project Below
This is a very simple demo to show you how things should look and feel after following this tutorial.
Hope it helps.

View attachment 16609



This is a fundamental article. It should be put stuck on the home page of the site!

Since I can not explain well in English, briefly:

After developing most of my app, I realized that, depending on the device (API) on which it would be installed, he could use Holo Light or Dark. A disaster! The black text on a black background disappeared, of course, and white ones ...!

Just a few minutes ago I was reading the page: http://developer.android.com/guide/topics/ui/themes.html and I was going to post it here (this site) a request for clarification, but then I searched and found this excellent tutorial!

Many thanks, BarX
 

LucaMs

Expert
Licensed User
Longtime User
I hate the look of some controls of the holo style and this style also creates problems with the colors of the texts (depending on whether you are using dark or light).

To avoid these styles, I do not specify the target sdk int the manifest file, leave only minsdk = 4.

The problem is that I do not like the title bar of the older version.

I have read that the themes can be inherited and you can then "override" some parts of them.
How should I do in my case? Put a style for titlebar in \ res \ values \
and do not create the \ res \ values-v11 \? How?

I thank you in advance
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello,

Compliling the Demo project with on B4A 3.20, I have got this error

Parsing code. 0.02
Compiling code. 0.09
Compiling layouts code. 0.01
Generating R file. Error
res\values-v11\styles.xml:4: error: Error retrieving parent for item: No resource found that matches the given name '@android:style/Theme.Holo.Light'.
res\values-v11\styles.xml:8: error: Error retrieving parent for item: No resource found that matches the given name '@android:style/Theme.Holo.Light.NoActionBar'.
res\values-v11\styles.xml:12: error: Error retrieving parent for item: No resource found that matches the given name '@android:style/Theme.Holo.Light.Panel'.

I only copied and pasted the demo folder and would like to know if the demo is still usable. Thanks
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello thedesolatesoul,

Thanks for the reply. I was refering to android-8. It works now. Sorry
 

Peter Simpson

Expert
Licensed User
Longtime User

luciano deri

Active Member
Licensed User
Longtime User
Hello. Is possible change the style of activate without change the style of edit text? Because for different style i must change the color text.
 

mrossen

Active Member
Licensed User
Longtime User
Hi,

How will this effect with Android L (5.0) Material design?

Mogens
 

RandomCoder

Well-Known Member
Licensed User
Longtime User

AscySoft

Active Member
Licensed User
Longtime User
Isn't Theme_Holo_Light_NoActionBar introduced in api 13?
See http://developer.android.com/reference/android/R.style.html
Look for Constant Value: 16974064 (0x010300f0)

So in this case using an custom xml theme like in your fine tutorial and setting this
B4X:
SetApplicationAttribute(android:theme, "@style/MyThemeNoTitle")
in manifest, is not so good for api 12 devices.
Am I wrong?
 
Last edited:

tonymonaghan

Member
Licensed User
Longtime User
Thanks, works great.
Can you use Theme.Dark, Theme.Holo.Dark etc? I tried it and got the following error.


Generating R file. Error
res\values\styles.xml:4: error: Error retrieving parent for item: No resource found that matches the given name 'android:style/Theme.Dark'.
res\values-v11\styles.xml:4: error: Error retrieving parent for item: No resource found that matches the given name '@android:style/Theme.Holo.Dark'.

I have configured my paths to use sdk version 22

Thanks
 

barx

Well-Known Member
Licensed User
Longtime User
Technically you can use any parent theme that is available I the relevant android version...
 
Top