Android Tutorial Material Design 3 - Using a ToolBar as ActionBar

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

Google recommends to use a ToolBar instead of the standard system ActionBar for Material Design apps. In this tutorial we will use a ACToolBar(Light/Dark) object from the AppCompat library (1.10 and above) as an ActionBar.

One of the main differences between a ToolBar and the standard ActionBar is that the ActionBar is a system component which is automatically added by the os and a ToolBar is part of our layout so we can add it to the activity with the designer or by code.

Using the ToolBar object

First we need to set up our project like in the Material Design 2 tutorial.
Then we need to add some more items to the theme:

B4X:
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">true</item>

This disables the standard ActionBar in the theme. With the windowActionModeOverlay set to true ActionMode Actionbars will replace the ToolBar and are not displayed above it.

Now we can create our layout. For the example project I decided to split the layout into two parts. One "main" layout which contains the ToolBar and a simple Panel for the content.
So add a CustomView of type "ACToolBarLight" to a new layout called "main" and set the following properties:

Layout_ActionBar.png


Note that "Use as main ActionBar" is checked to use this Toolbar as the main ActionBar for the Activity. You can only use one Toolbar as the Activity ActionBar.
Elevation should be set to 4 for a normal ActionBar. This will produce a small shadow below it.
Additionally you should disable the Background color in the properties.

There are two versions of the ToolBar object. ACToolBarLight uses a light theme and ACToolBarDark uses a dark theme by default. This is only for historical reasons. You can set the light or dark theme for the ToolBar and the overflow menu with the designer properties now.

Now we add a Panel named pContent to the Layout with the following properties:

Layout_pContent.png


Because the standard height of the ToolBar/ActionBar in Material Design depends on the device orientation and screen size we add a small designer script:
B4X:
If ActivitySize > 6.5 Then
  ActionBar.Height = 64dip
Else
  If Portrait Then
    ActionBar.Height = 56dip
  Else
    ActionBar.Height = 48dip
  End If
End If

pContent.SetTopAndBottom(ActionBar.Bottom, 100%y)
This will set the ActionBar height to 64dip on tablets and to 56dip on portrait phones and 48dip on landscape phones. These specifications are in the Material Design guide.

Now we have a minimal example of how to setup a ToolBar as an ActionBar.

ToolBar_Shadow.png


Misc stuff

You can use the ACActionBar object to control some ActionBar features like showing the "Up" indicator arrow.

B4X:
Dim ABHelper as ACActionBar

ABHelper.ShowUpIndicator = True

Adding actions and overflow menu

You can use the normal Activity.AddMenuItem() methods to add a menu or actions to the ToolBar:

B4X:
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")

I prefer to use drawables for action icons than use the LoadBitMap() function. The drawables are available in different resolutions and will always load in the perfect size for your device. To load drawables you will have to use the XmlLayoutBuilder library.

The attached example has some UI elements to control some features of the ToolBar. Have fun with it.

ExampleApp.png
 

Attachments

  • ACToolBarExample2_0.zip
    25.3 KB · Views: 3,899
Last edited:

Anser

Well-Known Member
Licensed User
Longtime User

Anser

Well-Known Member
Licensed User
Longtime User
I just came back to the msiconicdrawable setup and it works perfectly. Code for my setup is below

B4X:
    uxActionBar.SetAsActionBar
    uxActionBar.Title = "Dashboard"
    Dim icon As MSIconicDrawable : icon.Initialize("gmd_menu")      : icon.Color = Colors.white
    icon.actionBarSize
    uxActionBar.NavigationIconDrawable = icon.Drawable

and in the menu setup pretty much the same thing again

B4X:
Dim item As ACMenuItem
    Dim icon As MSIconicDrawable : icon.Initialize("gmd_sync")      : icon.Color = Colors.white
    icon.actionBarSize
    Menu.Add2(1, 1, "Sync",  icon.Drawable).ShowAsAction = item.SHOW_AS_ACTION_ALWAYS

This is great as it really cuts out a massive amount of hassle using icons. I've now used this in a variety of places in my code and the simplification is great :)
Dear joneden,

I am able to use the MsIconicDrawable for the NavigationIconDrawable ie the first one code provided by you , but unable to make use of MsIconicDrwable on the second code ie using AcMenuItem, could not understand what type of object is "Menu" in your code "Menu.Add2((1, 1, "Sync", icon.Drawable).ShowAsAction = item.SHOW_AS_ACTION_ALWAYS"

As of now I am using the code provided by corwin ie
B4X:
    Dim xml As XmlLayoutBuilder
    Dim bd As BitmapDrawable
    bd = xml.GetDrawable("ic_refresh_black_24dp")
    Activity.AddMenuItem3("Refresh", "MenuRefresh", bd.Bitmap, True)

I am unable to replace bd.Bitmap with bd.drawable, it will throw error.


How to use MSIconicDrawable to show the refresh button (Black color) on the ActionBar ? The black one displayed on the picture is a BitmapDrawable.
Screenshot.png


Would you mind helping me.

Regards
Anser
 

Cnrez

Member
Licensed User
Longtime User
hi again,

i want to change the color of text on actionbar
TitleTextColor and SubTitleTextColor
with these values :
#212121 and #727272

how do i write the syntax ?

ActionBar.SetAsActionBar
ActionBar.TitleTextColor ?
ActionBar.SubTitleTextColor ?


thanks

<color name="primary_text">#212121</color>
<color name="secondary_text">#727272</color>
 

Anser

Well-Known Member
Licensed User
Longtime User
i want to change the color of text on actionbar
TitleTextColor and SubTitleTextColor
with these values :
#212121 and #727272

I am also looking for a solution to change the Color of the Title/SubTitle text.

Right now, I understand that you need to decide upon a Parent theme either DARK or LIGHT
If you choose Theme DARK, then you will have the Texts on Title/SubTitle in White Color, if you choose LIGHT theme then the TitleText/SubTitle Text will be displayed in Black color.

May be the experts here will give you a solution, I just shared the information that I know.

I am yet to get a reply regarding using Drawable Icons using MSIconicDrawable on the ActionBar. It will avoid lot of unnecessary troubles in handing different images with different colors and resolutions.

Regards

Anser
 
Last edited:

ArminKH

Well-Known Member
@corwin42
hi is there any way to change the position of some child of toolbar?
for example i want to set Left property for title or i want to set left property for Navigation icon
i know all of them are adjusted by material design standard values but for some reason i need to change the layout of views programically after compile
for example i need to set the Left and Top and Height and Width of title bar and,etc... after compile with an animation
is there any way? maybe in java?
when i want to get views left property the log window show the message which is "Layout is not available"
thank u
 

corwin42

Expert
Licensed User
Longtime User
@corwin42
hi is there any way to change the position of some child of toolbar?
for example i want to set Left property for title or i want to set left property for Navigation icon

No, this is not supported. Be aware that the Toolbar is a standard Android component which is built by xml layout files which don't use the absolutelayout like B4A uses it for its designer created layouts. So there is no left and top, width and height property which could be used. If you need such custom layouts maybe you can use a simple transparent panel and put it on top of the Toolbar.
 

ArminKH

Well-Known Member
ok thank u
i can create my own toolbar but it seems other wrapper classes are just works with app combat toolbar
for example how to use ACMenu wrapper with my own toolbar which is created by panels,labels,etc... same to ACSearchView wrapper class?
 

corwin42

Expert
Licensed User
Longtime User
ok thank u
i can create my own toolbar but it seems other wrapper classes are just works with app combat toolbar
for example how to use ACMenu wrapper with my own toolbar which is created by panels,labels,etc... same to ACSearchView wrapper class?

This is not supported, then.
 

corwin42

Expert
Licensed User
Longtime User
(note that B4A is not based on AbsoluteLayout)
Yes, sorry. You are of course correct but it is very similar at least both have top, left, width and height properties so objects could be positioned with absolute coordinates. The internal Toolbar layout do not use layouts with absolute positioning.
 

paragkini

Member
Licensed User
Longtime User
Hi,
I have tried doing this project but while following tutorial 3, (it worked for tutorial 1 and 2) I am not able to compile the code.
Keep getting different errors. Also updated Android tools through SDK manager. Now I have stopped on below error.

B4X:
B4A version: 5.80
Parsing code.    (0.00s)
Compiling code.    (0.59s)
Compiling layouts code.    (0.01s)
Generating R file.    (7.78s)
Compiling generated Java code.    Error
javac 1.7.0_45
src\b4a\example\main.java:17: error: cannot find symbol
public class main extends android.support.v7.app.AppCompatActivity implements B4AActivity{
                                                ^
  symbol:   class AppCompatActivity
  location: package android.support.v7.app
Note: src\b4a\example\starter.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error

screenshot of settings.
b4aUntitled.png


SDK settings.
androidsdk.png
 

paragkini

Member
Licensed User
Longtime User
thanks corwin42, after a few searches have managed to put the correct file in additional libraries folder and it compiled without error.
However compiled app now doesn't run and gives "app has stopped error" upon execution. Guess need to do some more cleanup. Will check and come back if help needed...


[Update] there was a problem with android-support-v4 file. after replacing it, it started working. Thanks for your help.
 
Last edited:

Cnrez

Member
Licensed User
Longtime User
hi, solved

add this in your themes.xml file


<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#2196F3</item>
<item name="colorPrimaryDark">#1976D2</item>
<item name="colorAccent">#00BCD4</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:textColorPrimary">#color whatever you want</item>
<item name="android:textColorSecondary">#color whatever you want</item>

</style>
</resources>


hi again,

i want to change the color of text on actionbar
TitleTextColor and SubTitleTextColor
with these values :
#212121 and #727272

how do i write the syntax ?

ActionBar.SetAsActionBar
ActionBar.TitleTextColor ?
ActionBar.SubTitleTextColor ?


thanks

<color name="primary_text">#212121</color>
<color name="secondary_text">#727272</color>
 

rudystyle

Member
Licensed User
Longtime User
Firstly thanks for the libraries and the amount of work that you have given away for free.
I made a small token donation of €10.00 to your paypal.
_______________________________________________________
I tried out a simple example and everything works fine.
However when I use the MsgBox function. The app crashes and in the debug window there is the error
java.lang.NoSuchMethodError: android.support.v4.view.ViewCompat.hasOnClickListeners
at android.support.v7.app.AppCompatViewInflater.checkOnClickListener(AppCompatViewInflater.java:196)
.
.
.


B4X:
Region  Project Attributes

#AdditionalRes: ..\resource  

#AdditionalRes: $AdditionalLibs$\resource\b4a_appcompat, de.amberhome.objects.appcompat
#AdditionalRes: $AndroidSDK$\extras\android\support\v7\appcompat\res, android.support.v7.appcompat

#Extends : android.support.v7.app.ActionBarActivity

    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False

#End Region

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.

    Private ActionBar As ACToolBarLight
    Private pContent As Panel
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 (it is called ActionBar in the layout file) as the ActionBar of this activity.
ActionBar.SetAsActionBar

'Set Title and Subtitle for the ToolBar
ActionBar.Title = "AppCompat"
ActionBar.SubTitle = "ToolBar Example 1"


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)

End Sub

Sub Menu_Click
    Log("Clicked")
    Msgbox("sss","")
   
     
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

corwin42

Expert
Licensed User
Longtime User
Firstly thanks for the libraries and the amount of work that you have given away for free.
I made a small token donation of €10.00 to your paypal.
_______________________________________________________
I tried out a simple example and everything works fine.
However when I use the MsgBox function. The app crashes and in the debug window there is the error
java.lang.NoSuchMethodError: android.support.v4.view.ViewCompat.hasOnClickListeners
at android.support.v7.app.AppCompatViewInflater.checkOnClickListener(AppCompatViewInflater.java:196)
.

NoSuchMethodErrors in one of the support libraries normally show that you have an outdated version of the support library installed in your B4A CustomLibs folders.

If the error is really related to the MsgBox call can you please post the full stacktrace?
 

divinglog

Member
Licensed User
Longtime User
Hi

When I select text in a TextView, the text selection toolbar does not overlay the app toolbar. Instead both toolbars are stacked, which looks really odd. Is there a way to prevent this? Is there an event for the text selection toolbar showing, so I can hide the app toolbar?

Screenshot_2016-06-08-21-09-13.png Screenshot_2016-06-08-21-09-20.png
 

corwin42

Expert
Licensed User
Longtime User
How to hide and show Toolbar when list is scrolling. Pl. suggest

Unfortunately there is no simple way to do this. The ListView and ScrollView objects do not have the necessary events to handle this. If you use UltimateListView you can listen to events like scrollstatechange to hide or show the Toolbar.

Hi

When I select text in a TextView, the text selection toolbar does not overlay the app toolbar. Instead both toolbars are stacked, which looks really odd. Is there a way to prevent this? Is there an event for the text selection toolbar showing, so I can hide the app toolbar?

Please try to add this to your theme:
B4X:
<item name="windowActionModeOverlay">true</item>
 
Top