Android Tutorial Material Design 2 - Using the AppCompat library

corwin42

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

In the first Material Design tutorial we created a simple app with Material Design for Android 5.0 (Lollipop) devices. But what about older Android versions?
For compatibility with older devices Google created the support libraries which brings new features to older Android releases. For Material Design the most important support library is the AppCompat library. This tutorial will show how to use the AppCompat library with B4A.


Setting up AppCompat library
For this tutorial we need the AppCompat wrapper library. Please set it up as explainded in the first post of the library thread.

First we need to add the AppCompat library to our project. For this check the AppCompat library in the libs tab of the IDE.

Next thing to know is that every Activity which uses AppCompat features has to extend the android.support.v7.app.AppCompatActivity. This can be done with the #Extends attribute in the activity modules.

B4X:
 #Extends: android.support.v7.app.AppCompatActivity
Setting up the theme
If we want to use AppCompat, we must use an AppCompat theme. Because we want to configure some colors in the theme we set up our own theme resource in the Manifest Editor:

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

CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="@style/Theme.AppCompat">
        <item name="colorPrimary">#FF9800</item>
        <item name="colorPrimaryDark">#F57C00</item>
        <item name="colorAccent">#FFA726</item>
    </style>
</resources>
)
As you can see we use a parent of Theme.AppCompat for our example. There are also Theme.AppCompat.Light or Theme.AppCompat.Light.DarkActionBar themes like the standard Material Design themes. Additionally to the theme name we set colorPrimary, colorPrimaryDark and colorAccent. See the first Material Design tutorial for an explanation of these colors.

So let's see how our app looks like. For the first example I just added some UI elements like EditText, CheckBox, RadioButton, Spinner, ...

MaterialExample_Lollipop_wrong_scaled.png
MaterialExample_KitKat_wrong_scaled.png


On Lollipop devices this looks nice but there seems to be something wrong with pre Lollipop devices like KitKat, JellyBean or even Gingerbread. The UI elements like EditText, CheckBox and RadioButton just show black and are hard to see on the dark theme.
This is because the way B4A creates its views in the designer is not compatible with the AppCompat library. The AppCompat wrapper library contains some views which are compatible with AppCompat. Instead of EditText, CheckBox or RadioButton just use ACEditText, ACCheckBox and ACRadioButton views. These can be added as CustomViews in the designer or they can be added to the Activity (or to a Panel) manually by code just like the standard views.

Additionally there is a new ACSwitch view which looks like the standard on/off switch.
In the second attached example all these views are used as a CustomView with the designer. The examples should work on all devices with API 7 or above. On GingerBread devices there is not the nice coloring of the views but the app should still work.

MaterialExample_Lollipop_ok_scaled.png
MaterialExample_KitKat_ok_scaled.png
MaterialExample_Ginger_ok_scaled.png


Notice that on Gingerbread devices there is no overflow menu anymore.
 

Attachments

Last edited:

thedesolatesoul

Expert
Licensed User
Thanks a lot corwin42 for this effort and for all of the explanations. Its a great job.

This is because the way B4A creates its views in the designer is not compatible with the AppCompat library. The AppCompat wrapper library contains some views which are compatible with AppCompat. Instead of EditText, CheckBox or RadioButton just use ACEditText, ACCheckBox and ACRadioButton views.
I'll be honest with you, I dont like this. We dont want two libraries to have the basic widgets duplicated. Also it is alot of work.

Additionally there is a new ACSwitch view which looks like the standard on/off switch.
Thanks for this, I was searching all over for this.
 

Inman

Well-Known Member
Licensed User
On Lollipop devices this looks nice but there seems to be something wrong with pre Lollipop devices like KitKat, JellyBean or even Gingerbread. The UI elements like EditText, CheckBox and RadioButton just show black and are hard to see on the dark theme.
This is because the way B4A creates its views in the designer is not compatible with the AppCompat library.
What about views created manually by code? Will they have the Lollipop look or should we still use ACEditText?
 

corwin42

Expert
Licensed User
I'll be honest with you, I dont like this. We dont want two libraries to have the basic widgets duplicated. Also it is alot of work.
I had some solutions in mind. The easiest would be for us developers if Erel changes the core library. The change to the views would be minimal. Only some resources need to be added to every app. This could be handled internally. Maybe I will discuss it with Erel but it is an elemental change and I would understand Erel if he refuses to make the change.

Another solution I thought of was to create a method that replaces all views created with the designer. So you would have to call just this method after a LoadLayout. This is possible but a lot of work to replace all the event calls for the views and would produce a lot of overhead.

So I think the current solution is the most practible.

What about views created manually by code? Will they have the Lollipop look or should we still use ACEditText?
You will have to use the AC versions.
 

Peter Simpson

Expert
Licensed User
Hello @corwin42, this is an excellent tutorial. I notice that I no longer need the folder in my resources, values-v21 :)

Bad new though, well you're still working on this solution so all has been forgiven already, it's nothing serious though.
As you are well aware, Android 5.0 Lollipop (SDK 21) now come with tap animation on the views. Well I decided to test your checkbox and radiobutton that you have kindly included as custom views. They work as expected but if you look at my screen shot below, you will notice that as I tapped the radiobutton the Android 5.0 pebble splash effect as I call it starts to animate, the left hand side of the animation gets cut off. Please look at the radiobutton just past half way down my screen shot, you will see that the left hand side is not a semi circle, but a straight line, the checkbox does the exact same thing too. Please note that the customview is about half the size of the screen shot. This screen shot was taken on my N5 running Android 5.0.1. Thanks again for your hard work and dedication, cheers...

Screenshot_2014-12-20-05-13-24.png
 

corwin42

Expert
Licensed User
I see it. Haven't noticed so far. Problem is the way the B4A designer creates Custom views. They are surrounded by a panel and this panel cuts off the ripple effect. Without the panel the new layout animations won't work.
I have an idea how to solve this. Would be a little hack but maybe it will work.
 

Peter Simpson

Expert
Licensed User
Hello again,
Thank you for creating the AppCompat library and this great tutorial.

Two things though.
1. You have already mentioned the spinner, that looks just like another work an pre-android 5.0 apps. There's no visual indicator to let users know that it's an actual spinner, but you already know that.

2. AcActionBar can not be written as follows, AcActBar.Initialize("Anything"), so there's no click even.

Thank you again, and keep up the great work...
 

corwin42

Expert
Licensed User
Hello again,
Thank you for creating the AppCompat library and this great tutorial.

Two things though.
1. You have already mentioned the spinner, that looks just like another work an pre-android 5.0 apps. There's no visual indicator to let users know that it's an actual spinner, but you already know that.

2. AcActionBar can not be written as follows, AcActBar.Initialize("Anything"), so there's no click even.

Thank you again, and keep up the great work...
1. For the Spinner there is only the small triangle as the indicator that it is a spinner. This is normal. Only problem with spinner is that the colors are sometimes not correct and the small triangle is not colored on pre Lollipop devices when the spinner is clicked. I think these are minor problems and for the colors there is a simple workaround (set the colors in code)

2. The click event of the StdActionBar does not work on Android 5.0. Use Activity_ActionBarHomeClick event instead (see B4A 4.0 release notes). Be aware that in Material Design the home button is only clickable, when you set AcActBar.ShowUpIndicator = True

Btw: I have fixed the cut off ripple effect. Will be available with the next version of the library.
 

thedesolatesoul

Expert
Licensed User
I had some solutions in mind. The easiest would be for us developers if Erel changes the core library. The change to the views would be minimal. Only some resources need to be added to every app. This could be handled internally. Maybe I will discuss it with Erel but it is an elemental change and I would understand Erel if he refuses to make the change.

Another solution I thought of was to create a method that replaces all views created with the designer. So you would have to call just this method after a LoadLayout. This is possible but a lot of work to replace all the event calls for the views and would produce a lot of overhead.
What is the change that allows it to become material? Are you re-inflating from a layout?
 

corwin42

Expert
Licensed User

corwin42

Expert
Licensed User
Is it possible to read the colors at runtime?
Yes, there is a method in the AppCompat library for it:

B4X:
Dim ac as AppCompat
Dim colorPrimary as Int

colorPrimary = ac.GetThemeAttribute("colorPrimary")
 

corwin42

Expert
Licensed User
Any news about the tutorial with a ToolBar object?
I'm working on it. With it the AppCompat library will get a huge update.
I hope to release it at the end of the week.
 
Top