Android Tutorial Material Design 1 - Basics

corwin42

Expert
Licensed User
Note: You should use B4A 6.0 or above for this tutorial.

Android 5.0 (also called "Lollipop") introduced a new design for apps called "Material Design".

With this tutorial series I will introduce some of the Material Design guidelines and explain some differences to the Holo Design.

For a good start it will be helpful if you know what material design is so it is a good idea to spend some time to study the first few chapters of the official Google "Material Design" guidelines.

Basic Material Example

In this tutorial we will create a very simple app that uses Material design on Android 5.0+ (Lollipop, Marshmallow, Nougat and above) devices and the normal Holo design on Android 4.0 devices.

Important:
Because we use features of the SDK version 21 you have to configure the correct android.jar in the Configure Paths dialog of the IDE. Set the path for android.jar to at least <Your_Android_SDK_HOME>\platforms\android-21\android.jar. You should always use the latest android.jar that is available like android-24/android.jar. Don't worry. Your app will run on older Android versions, too.

Android always uses a theme for the UI. The default theme of an app depends on the installed OS version and the targetSdkVersion specified in the manifest of the app.
  • A targetSdkVersion up to 10 results in the old Classic Android theme on all OS versions.
  • targetSdkVersion of 11 up to 13 results in a dark Holo theme on OS versions 3.0+ (Honeycomb and up).
  • If targetSdkVersion is 14 or above, the app will have Holo theme on OS versions up to 4.4 (KitKat) and (this is a bit strange) Material theme on 5.0 (Lollipop).
I would have expected Holo theme until targetSdkVersion is set to 21 or above but that is not the case.
Therefore it is a good idea to explicitly set a Holo theme if your current app does not really support Material Design. There are some changes in Material Design theme that will probably break your app.
Be aware that setting targetSdkVersion affects the default theme. You can explicitly set another theme in the manifest if you want.

Best practice is to set targetSdkVersion to the highest OS version number your app should support and it has been tested on. So for our example app we set it to 21.
The minSdkVersion has to be set to the lowest OS version number the app should support. Since our app will use the ActionBar and the StdActionBar library this will be OS version 11 (Honeycomb). So we have to change the following line in the Manifest Editor:

B4X:
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="21"/>
This will enable the default dark Material theme on Android 5.0 Lollipop devices.

Using our own Theme

Because we want to use the light Material theme (with a dark ActionBar) and not the dark one in our app and we want to use custom colors for the ActionBar and StatusBar we have to create our own theme resource file. There are several ways to create resource files.
  1. You can save them in <project-home>\Objects\res folder and make the files read only.
  2. You can create your own folder for resouce files and add it to B4A with #AdditionalRes attribute.
  3. You can create the resource files with CreateResource() in the Manifest editor.
I prefer to use the third method, so we add the following lines to the Manifest editor:

B4X:
CreateResource(values-v21, themes.xml,
<resources>
    <style name="MyAppTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
        <item name="android:colorPrimary">#FF9800</item>
        <item name="android:colorPrimaryDark">#F57C00</item>
        <item name="android:colorAccent">#FFA726</item>
    </style>
</resources>
)
The theme declares three attributes:

colorPrimary - This color is the main color for the app and is used for example as the ActionBar background
colorPrimaryDark - This color is used for the StatusBar
colorAccent - This is the AccentColor used for other UI elements like checkboxes, radio buttons etc.

So if we set these three attributes we can change the whole appearance of our app. Note that the colors defined here are also used in the systems task manager on Lollipop devices.

The material design guidelines gives some hints of what colors should be used in an app. Please study these pages about colors for further information.

Now we have to set our custom theme in the Manifest Editor:

B4X:
SetApplicationAttribute(android:theme, "@style/MyAppTheme")
Ok, now we have set the theme for Android Lollipop (5.0) devices. But what about the other versions like Jelly Bean (4.x) or KitKat (4.4)?
We simply add a theme that sets the Holo theme for the app. So we add the following lines to the Manifest editor:

B4X:
CreateResource(values, themes.xml,
<resources>
    <style name="MyAppTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
    </style>
</resources>
)
So we have now set Material theme on Lollipop (and higher) devices and Holo theme on lower Android versions.

Differences between Holo and Material Design

So what are the main differences between the Holo theme and Material theme?
Here are some screenshots of the example app with the differences. In addition to some visual enhancements there are some very important changes:

Example_Holo1_scaled.png
Example_Material1_scaled.png


  • No Application Icon in ActionBar - In Material Design there is no Application Icon in the ActionBar. Though it is still possible to show the up-arrow or a menu icon. This will be shown in a later tutorial.
  • Different ActionBar Height - ActionBar height should be 48dip on landscape phone, and 56dip in portrait. On tablets it should always have 64dip.
  • Buttons floating above all other views - With Material Design every visible "object" has an elevation value. Buttons by default have an elevation of 2dip though floating above other views. View.BringToFront() does not work anymore on buttons!
  • List Popups and Menus start over root object and not below - As you can see in the screenshots the overflow menu overlaps the ActionBar on Material Design.
I hope this tutorial gives you a good start to Material Design. In the next tutorial I will explain how to use the AppCompat support library to create Material Design apps even for pre Lollipop devices.
 

Attachments

Last edited:

thedesolatesoul

Expert
Licensed User
Thanks @corwin42, keep going.

You can further customize your pre-L actionbar to a different height and textsize using:

B4X:
<resources>
    <!-- the theme applied to the application or activity -->
    <style name="CustomActionBarTheme"
           parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>

    <!-- ActionBar styles -->
    <style name="MyActionBar"
           parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@drawable/actionbar_background</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:height">56dp</item>
        <item name="android:titleTextStyle">@style/MyTitleTextStyle</item>
    </style>
   
    <style name="MyTitleTextStyle" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:textSize">20sp</item>
    </style>
</resources>
 

stevel05

Expert
Licensed User
Thank you for sharing your research.:)
 

derez

Expert
Licensed User
Thanks @corwin42 !
I have a problem, getting this error when compiling:
Parsing code. 0.00
Compiling code. 0.01
Compiling layouts code. 0.01
Generating R file. Error
res\values-v21\themes.xml:3: error: Error retrieving parent for item: No resource found that matches the given name '@android:style/Theme.Material.Light.DarkActionBar'.
res\values-v21\themes.xml:6: error: Error: No resource found that matches the given name: attr 'android:colorAccent'.
res\values-v21\themes.xml:4: error: Error: No resource found that matches the given name: attr 'android:colorPrimary'.
res\values-v21\themes.xml:5: error: Error: No resource found that matches the given name: attr 'android:colorPrimaryDark'.
The files are read_only and I tried both places - /Resources like in the example, and /objects/res like explained.
I see the layout in the designer but it doesn't run.
Help ?
 

corwin42

Expert
Licensed User
Thanks @corwin42 !
I have a problem, getting this error when compiling:

The files are read_only and I tried both places - /Resources like in the example, and /objects/res like explained.
I see the layout in the designer but it doesn't run.
Help ?
You have to use the android.jar of platform version 21 in the "Configure Paths" options of the B4A IDE.

I will add it to the tutorial, thanks.
 

derez

Expert
Licensed User
You have to use the android.jar of platform version 21
Of course, shame on me...Thanks.
Now I am updating my android sdk files for something else that is missing.
 

derez

Expert
Licensed User
After configuring the above I got this error:
A referenced library is missing: android-support-v4
I found that it is installed in the android sdk but for some reason it is not found by the application.
I copied it to the library and refernced it :
#AdditionalJar: android-support-v4.jar
This time it runs ok.
deleting the #AdditionalJar line doesn't change - it works, but must be in the library.
What's wrong ?
 

corwin42

Expert
Licensed User
Thanks @corwin42, keep going.

You can further customize your pre-L actionbar to a different height and textsize using:

B4X:
<resources>
    <!-- the theme applied to the application or activity -->
    <style name="CustomActionBarTheme"
           parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>

    <!-- ActionBar styles -->
    <style name="MyActionBar"
           parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@drawable/actionbar_background</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:height">56dp</item>
        <item name="android:titleTextStyle">@style/MyTitleTextStyle</item>
    </style>
  
    <style name="MyTitleTextStyle" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:textSize">20sp</item>
    </style>
</resources>
Thanks for the hint. You can even colorize the Holo ActionBar with the Android Assets Studio. This possibility exists for a long time now. I haven't explained it here because the goal is to get Material Design on all Android versions with the AppCompat library. This will be addressed in the next tutorial.
 

thedesolatesoul

Expert
Licensed User
Thanks for the hint. You can even colorize the Holo ActionBar with the Android Assets Studio. This possibility exists for a long time now. I haven't explained it here because the goal is to get Material Design on all Android versions with the AppCompat library. This will be addressed in the next tutorial.
Thanks. I tried to style the AB to Material theme, well before the AppCompat was released. Now I am waiting for Toolbar. I'm hoping the next tutorial is coming today!
 

corwin42

Expert
Licensed User
After configuring the above I got this error:

I found that it is installed in the android sdk but for some reason it is not found by the application.
I copied it to the library and refernced it :

This time it runs ok.
deleting the #AdditionalJar line doesn't change - it works, but must be in the library.
What's wrong ?
The example only adds the StdActionBar library which does not rely on any other support libraries.
 

corwin42

Expert
Licensed User
Thanks. I tried to style the AB to Material theme, well before the AppCompat was released. Now I am waiting for Toolbar. I'm hoping the next tutorial is coming today!
Sorry, no. Maybe at the weekend. Need to clean up some things. Next tutorial will address simple AppCompat usage. Toolbar will follow then.
 

derez

Expert
Licensed User
Changing the code of menuitens to actionbar list I got the following, with dark text on dark background, on both versions of android - 5.0 and 4.4 :
B4X:
SAB.NavigationMode = SAB.NAVIGATION_MODE_LIST
Dim list1 As List
list1.Initialize
list1.Add("Item1")
list1.Add("Item2")
list1.Add("Item3")
SAB.SetListItems(list1)
How can I change the textcolor ?
 

Attachments

corwin42

Expert
Licensed User
Changing the code of menuitens to actionbar list I got the following, with dark text on dark background, on both versions of android - 5.0 and 4.4 :
B4X:
SAB.NavigationMode = SAB.NAVIGATION_MODE_LIST
Dim list1 As List
list1.Initialize
list1.Add("Item1")
list1.Add("Item2")
list1.Add("Item3")
SAB.SetListItems(list1)
How can I change the textcolor ?
I think you have to change the Theme like in this Stackoverflow answer. But be aware that for Material Design list navigation and tab navigation is deprecated and should not be used anymore.
 

derez

Expert
Licensed User
@corwin42 said:
But be aware that for Material Design list navigation and tab navigation is deprecated and should not be used anymore.
So, I'm not looking for it anymore.
Not underestimating the work done on it, I really don't understand the big fuss about material design. I'll wait for the coming tutorials and see what else is in it.
What really drives me nuts is Google's decision that text on buttons must be in capitals, and that buttons are above all other views in importance.
Down with the buttons :mad:
 

TpS

Member
Licensed User
Is it in anyway possible to place an Panel in front of a button using Material design?

I sometimes uses a panel as a settings box that I show in front of the objects in the activity.
In this case it contains a label explaining the setting and a spinner containing chooseable settings.
Using Holo, the panel is placed in front of every object and looks real nice, but now with Material design the buttons is still in front of my panel as I try to show it.
A sollution is ofcourse to hide the buttons but it would be nice to have a way to override the theme.
 

corwin42

Expert
Licensed User
Is it in anyway possible to place an Panel in front of a button using Material design?

I sometimes uses a panel as a settings box that I show in front of the objects in the activity.
In this case it contains a label explaining the setting and a spinner containing chooseable settings.
Using Holo, the panel is placed in front of every object and looks real nice, but now with Material design the buttons is still in front of my panel as I try to show it.
A sollution is ofcourse to hide the buttons but it would be nice to have a way to override the theme.
Currently not but I'm working on some libraries for material design. One of them is a ViewCompat library which will have a method to set the elevation for any view. With this it would be possible to put any view above a Button.
 
Top