Android Tutorial Material Design 2 - Using the AppCompat library

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

  • AppCompatExample1_2.0.zip
    8.1 KB · Views: 1,825
  • AppCompatExample2_2_0.zip
    8.3 KB · Views: 2,273
Last edited:

corwin42

Expert
Licensed User
Can't compile your Toolbar example, I get this (and yes, all paths are correct):

B4X:
Parsing code.                           0.03
Compiling code.                         0.41
Compiling layouts code.                 0.08
Generating R file.                      0.50
Compiling generated Java code.          Error
javac 1.8.0_25
src\de\amberhome\appcompat\toolbarexample1\main.java:17: error: cannot access SupportParentable
public class main extends android.support.v7.app.ActionBarActivity implements B4AActivity{
       ^
  class file for android.support.v4.app.TaskStackBuilder$SupportParentable not found
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
Seems that you have an old android-support.v4.jar in you custom libs folder. Did you update the support library in SDK Manager and copied both libraries (android-support-v4.jar and android-support-v7-appcompat.jar) to your custom libs folder? Check that you don't have an old version of the libraries in Basic4Android program folder.
 

migrec

Member
Licensed User
Seems that you have an old android-support.v4.jar in you custom libs folder. Did you update the support library in SDK Manager and copied both libraries (android-support-v4.jar and android-support-v7-appcompat.jar) to your custom libs folder? Check that you don't have an old version of the libraries in Basic4Android program folder.

That was it! thank you
 

corwin42

Expert
Licensed User
Is there a way to change the "textcolorPrimary" attribute?
Not programatically. Just put it in the Theme file like the other colors.
 

shashkiranr

Active Member
Licensed User
Hi All,

The activity home click is not recorded when no activity menu item is added. I have taken the below code from the example and commented the activity.addmenu and lines and made the pcontent as a scrollview.

I need an activity with just the up indicator and the click is not captured.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Dim AC As AppCompat
    Dim ABHelper As ACActionBar
    Private ActionBar As ACToolBarLight
    Private pContent As ScrollView
    Private cbABVisible As ACCheckBox
    Private cbABShadow As ACCheckBox
    Private cbShowAsUp As ACCheckBox
    Private edTitle As ACEditText
    Private edSubTitle As ACEditText
    Private cbShowLogo As ACCheckBox

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("main")

    'Set the Toolbar (from the loaded layout) as the ActionBar of this activity.
    ActionBar.SetAsActionBar

    'Set Title and Subtitle for the Toolbar
    ActionBar.Title = "AppCompat"
    ActionBar.SubTitle = "Toolbar Example 1"
   
    'Because the Toolbar is part of out layout we split up our layout in a main layout file
    '(which only has the Toolbar and a ContentPanel) and a content layout which has all the
    'visible controls.
'    pContent.LoadLayout("cardlayout")
'    pContent.Panel.LoadLayout("cardlayout")
    pContent.Panel.LoadLayout("content")
    'sync the controls with current state of ActionBar/Toolbar
    cbABVisible.Checked = True
    edTitle.Text = ActionBar.Title
    edTitle.Hint = "Title"
    edSubTitle.Text = ActionBar.SubTitle
    edSubTitle.Hint = "SubTitle"
   
    ABHelper.Initialize
    ABHelper.ShowUpIndicator = True
   

   
   
   
   
    'The AppCompat object has some helper methods to get the height for StatusBar, ActionBar and NavigationBar.
    'For the ActionBar there are two methods. GetStdActionBarHeight gets the standard ActionBar Height of the device.
    'Be aware that this is not necessarily the height defined by the material design guidelines. There is a second
    'method GetMaterialActionBarHeight which returns the ActionBar height as defined in the material design guidelines
    'regardless of the Android version.
    Log("ActionBar Height: " & (AC.GetMaterialActionBarHeight / DipToCurrent(1)))
   
    'Add some MenuItems
    'The best method to add action icons to the ActionBar/Toolbar is to load them as drawables.
    'With this method it is possible to load icons in different resolutions taking care of the device scale.
    'We use the XmlLayoutBuilder library to load the drawables.
'    Dim xml As XmlLayoutBuilder
'    Dim bd As BitmapDrawable
'    bd = xml.GetDrawable("ic_plus_one_black_24dp")
'    Activity.AddMenuItem3("Plus one", "Menu", bd.Bitmap, True)
'   
'    bd = xml.GetDrawable("ic_refresh_black_24dp")
'    Activity.AddMenuItem3("Refresh", "Menu", bd.Bitmap, True)
'   
'    Activity.AddMenuItem("Overflow1", "Menu")
'    Activity.AddMenuItem("Overflow2", "Menu")
'    Activity.AddMenuItem("Overflow3", "Menu")
'   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

'Show/Hide the Toolbar. This is done with the new SetLayoutAnimated and SetVisibleAnimated methods of B4A 4.0
Sub cbABVisible_CheckedChange(Checked As Boolean)
    If Checked Then
        ActionBar.SetLayoutAnimated(200, 0, 0, 100%x, AC.GetMaterialActionBarHeight)
        ActionBar.SetVisibleAnimated(200, True)
        pContent.SetLayoutAnimated(200, 0, AC.GetMaterialActionBarHeight, 100%x, 100%y - AC.GetMaterialActionBarHeight)
    Else
        ActionBar.SetLayoutAnimated(200, 0, 0, 100%x, 1dip)
        ActionBar.SetVisibleAnimated(200, False)
        pContent.SetLayoutAnimated(200, 0, 0, 100%x, 100%y)
    End If
End Sub

'Show/Hide Toolbar Shadow. This only works on Android 5.0 and above.
Sub cbABShadow_CheckedChange(Checked As Boolean)
    If Checked Then
        AC.SetElevation(ActionBar, 8dip)
    Else
        AC.SetElevation(ActionBar, 0dip)
    End If
End Sub

'Show Toolbar with "up" navigation icon.
Sub cbShowAsUp_CheckedChange(Checked As Boolean)
    If Checked Then
        ABHelper.ShowUpIndicator = True
    Else
        ABHelper.ShowUpIndicator = False
    End If
End Sub

'Sync edittext field with Toolbar Title
Sub edTitle_TextChanged (Old As String, New As String)
    If Old <> New Then
        ActionBar.Title = edTitle.Text
    End If
End Sub

'Sync edittext field with Toolbar Subtitle
Sub edSubTitle_TextChanged (Old As String, New As String)
    If Old <> New Then
        ActionBar.SubTitle = edSubTitle.Text
    End If
End Sub

'Show/Hide a Logo
Sub cbShowLogo_CheckedChange(Checked As Boolean)
    If Checked Then
        ActionBar.LogoBitmap = LoadBitmap(File.DirAssets, "b4a_180.png")
    Else
        ActionBar.LogoBitmap = Null
    End If
End Sub

'Handle Menu Click events. These are the normal B4A Menu item click events.
Sub Menu_Click
    Log("MenuItem " & Sender & " selected")
End Sub

Sub Activity_ActionBarHomeClick
    Log("activity home")
End Sub

Regards,
SK
 

corwin42

Expert
Licensed User
I did before asking
This is how it ends:
Error: No resource found that matches the given name: attr 'textcolorPrimary'
Hmm, try it with
<item name="android:textColorPrimary">...</item>
There are some posts on StackOverflow with people have some issues with it. Maybe it won't work.

Hi All,

The activity home click is not recorded when no activity menu item is added. I have taken the below code from the example and commented the activity.addmenu and lines and made the pcontent as a scrollview.

I need an activity with just the up indicator and the click is not captured.

The problem is the Toolbar that eats up the event. Use
ActionBar.InitMenuListener
and then you can use the
ActionBar_NavigationItemClicked event.
 

koaunglay

Member
Licensed User
I want to use material design. But I can't run any Material design Example. However I get error. When I run "AppCompatToolbarMenuExample" I get error-->
B4X:
B4A version 4.30
Parsing code.                           0.04
Compiling code.                         0.20
Compiling layouts code.                 0.06
Generating R file.                      Error
invalid resource directory name: ..\resource/drawable-xxxhdpi

So I deleted "drawable-xxxhdpi" folder. At the time I get this error-->
B4X:
B4A version 4.30
Parsing code.                           0.01
Compiling code.                         0.03
Compiling layouts code.                 0.00
Generating R file.                      Error
..\resource\values\themes.xml:6: error: Error: No resource found that matches the given name: attr 'colorAccent'.
..\resource\values\themes.xml:4: error: Error: No resource found that matches the given name: attr 'colorPrimary'.
..\resource\values\themes.xml:5: error: Error: No resource found that matches the given name: attr 'colorPrimaryDark'.

What is my error? Some body help me Please!!!
 

koaunglay

Member
Licensed User
Now I downloaded update
android-support-v4.jar and android-support-v7-appcompat.jar. But I get error--->
B4X:
B4A version 4.30
Parsing code.                           0.05
Compiling code.                         0.34
Compiling layouts code.                 0.02
Generating R file.                      Error
C:\Users\Koaunglay\Desktop\android-sdk\extras\android\support\v7\appcompat\res\layout\abc_action_bar_home.xml:29: error: Error: No resource found that matches the given name (at 'layout_marginTop' with value '@dimen/abc_action_bar_icon_vertical_padding').
C:\Users\Koaunglay\Desktop\android-sdk\extras\android\support\v7\appcompat\res\layout\abc_action_bar_home.xml:29: error: Error: No resource found that matches the given name (at 'layout_marginBottom' with value '@dimen/abc_action_bar_icon_vertical_padding').
 

corwin42

Expert
Licensed User
The exact steps of how to set up AppCompat libary can be found here.
Do you reference the API 21 android.jar? Did you check if all #AdditionalRes pathes are correct?
 

MhdBoy

Member
Licensed User
i have i big problem
when i compile my app the b4a get me this error

B4X:
B4A version 4.30
Parsing code.                           0.00
Compiling code.                         0.01
Compiling layouts code.                 0.00
Generating R file.                      Error
F:\Source\MaterialDesign\2-UsingAppCompact\AppCompatExample2\resource\values\themes.xml:6: error: Error: No resource found that matches the given name: attr 'colorAccent'.
F:\Source\MaterialDesign\2-UsingAppCompact\AppCompatExample2\resource\values\themes.xml:4: error: Error: No resource found that matches the given name: attr 'colorPrimary'.
F:\Source\MaterialDesign\2-UsingAppCompact\AppCompatExample2\resource\values\themes.xml:5: error: Error: No resource found that matches the given name: attr 'colorPrimaryDark'.

how i can fix it
i update my android-supports and i select API 21 for b4a
how i can fix it?
 

fishwolf

Well-Known Member
Licensed User
I get this error, but the path is correct

B4X:
B4A version 4.30
Parsing code.                           0.00
Compiling code.                         0.06
Compiling layouts code.                 0.00
Generating R file.                      Error
invalid resource directory name: C:\Programmi\Android\android-sdk\extras\android\support\v7\appcompat\res/drawable-ldrtl-xxxhdpi
invalid resource directory name: C:\Programmi\Android\android-sdk\extras\android\support\v7\appcompat\res/drawable-xxxhdpi
 

fishwolf

Well-Known Member
Licensed User
My guess: You have configured a very old android.jar under "Configure Paths".
Always use the latest platform version (currently android-22)

in b4a path i have configure version 21/22 of android.jar
into code you need set the resource path, i have see that appcompact folder is present only on v7 version.

but i reveive error when compile

B4X:
#AdditionalRes: ..\resource
#AdditionalRes: C:\Documents and Settings\Administrator\Documenti\ANDROID\Libraries\b4a_appcompat, de.amberhome.objects.appcompat
#AdditionalRes: C:\Programmi\Android\android-sdk\extras\android\support\v7\appcompat\res, android.support.v7.appcompat
#Extends: android.support.v7.app.ActionBarActivity
[/code[
 

corwin42

Expert
Licensed User
in b4a path i have configure version 21/22 of android.jar
into code you need set the resource path, i have see that appcompact folder is present only on v7 version.
Hmm, another idea. What build tools do you use. Because it complains only about the xxxhdpi folders maybe the build tools are too old. Check in SDK Manager what Android SDK build tools you use.
 

jotaele

Member
Licensed User
Hi:

I tried to change the background color of the overflow menu without success.

I tried to change the theme.xml, but always shows the same color.

Anybody has tried?
 

fishwolf

Well-Known Member
Licensed User
Hmm, another idea. What build tools do you use. Because it complains only about the xxxhdpi folders maybe the build tools are too old. Check in SDK Manager what Android SDK build tools you use.

i have all android component updated, i have resolved with delete folders of resource.

why?

4.30 version don't support xxx layout?
 

corwin42

Expert
Licensed User
i have all android component updated, i have resolved with delete folders of resource.

why?

4.30 version don't support xxx layout?

It should work with 4.30. (B4A version is not the problem here. It is an issue with outdated android.jar,build tools or library files).
 

fishwolf

Well-Known Member
Licensed User
It should work with 4.30. (B4A version is not the problem here. It is an issue with outdated android.jar,build tools or library files).

I'm try also with 5.02 version, the result i'ts the same.
The android sdk is updated

i have this error on 2 different PCs
B4X:
invalid resource directory name: C:\Programmi\Android\android-sdk\extras\android\support\v7\appcompat\res/drawable-ldrtl-xxxhdpi
invalid resource directory name: C:\Programmi\Android\android-sdk\extras\android\support\v7\appcompat\res/drawable-xxxhdpi

if i remove the tripel X layout the example app don't start.

Any Idea?
 
Top