Android Tutorial Material Design 3 - Using a ToolBar as ActionBar

Discussion in 'Tutorials & Examples' started by corwin42, Jan 6, 2015.

  1. corwin42

    corwin42 Expert Licensed User

    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:

    Code:
    <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:
    Code:
    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.

    Code:
    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:

    Code:
    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
     

    Attached Files:

    Last edited: Jul 31, 2016
    HAH, peacemaker, RauchG and 34 others like this.
  2. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Thanks corwin42. That is a LOT of work you had to go through to get the app material ready.
     
  3. corwin42

    corwin42 Expert Licensed User

    I think it is not that much. You have to set up a theme, set some attributes and use the theme in the manifest editor. That is the main setup for Material design.
    Everything else are addons or things you have to do with "normal" apps, too. You can still use the standard ActionBar with AppCompat but a ToolBar has some more features. For example you can place it everywhere you want and (upcoming in next tutorial) you can modify the menu at runtime.
     
    lemonisdead and DonManfred like this.
  4. DonManfred

    DonManfred Expert Licensed User

    Not when you already have a base-stock of this work....

    But if you setup a material app with appcompat the first time it looks complicated at the first sight... But it isn´t you are right.
     
  5. thedesolatesoul

    thedesolatesoul Expert Licensed User

    No, I meant the work YOU did i.e. creating all the libs and wading through the themes etc. :)
    Now you have made it easy for us, I still wish there was a template, I could just pick up and off I go.
     
  6. Peter Simpson

    Peter Simpson Expert Licensed User

    Cheers @corwin, this is fabulous stuff :)
    Your efforts are well appreciated from this side of the ocean...
     
    Last edited: Jan 6, 2015
    lemonisdead and DonManfred like this.
  7. Douglas Farias

    Douglas Farias Expert Licensed User

    very nice man thank you for the tutorial
     
  8. inakigarm

    inakigarm Well-Known Member Licensed User

    Great work corwin42 !!
     
  9. johndb

    johndb Active Member Licensed User

    This tutorial is excellent and your work, corwin42, is very much appreciated.
    I did notice that the shadow doesn't show on kitkat 4.4.2 or have I missed something?
     
  10. corwin42

    corwin42 Expert Licensed User

    Yes, as I said in the tutorial, setElevation only shows a shadow on Android 5.0 and above.
     
    Peter Simpson likes this.
  11. nadhiras

    nadhiras Member Licensed User

    Hi,
    Is it possible to use this toolbar for 2 or more activities ??
    because when i use two activities other activities (not Main Activities) can't set this tollbar as actionbar.

    its cannot handle "windowActionModeOverlay" at 2nd activies
     
  12. corwin42

    corwin42 Expert Licensed User

    It should work.

    What error do you get?
     
  13. nadhiras

    nadhiras Member Licensed User

    if i set toolbar.setasactionbar on 2nd activity i;ve got error like this:

    Code:
    ** Activity (main) Create, isFirst = true **
    ** 
    Activity (main) Resume **
    Menu ready to go!
    Unexpected 
    event (missing RaiseSynchronousEvents): cbitemvisible_checkedchange
    Check the unfiltered logs 
    for the full stack trace.
    ** 
    Activity (main) Pause, UserClosed = false **
    ** 
    Activity (two) Create, isFirst = true **
    Error occurred on line: 
    24 (two)
    java.lang.ClassCastException: de.amberhome.appcompat.toolbarmenuexample.two cannot be cast 
    to android.support.v7.app.ActionBarActivity
       at de.amberhome.objects.appcompat.ACToolBarWrapper.SetAsActionBar(ACToolBarWrapper.java:
    244)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    515)
       at anywheresoftware.b4a.shell.Shell.runVoidMethod(
    Shell.java:680)
       at anywheresoftware.b4a.shell.Shell.raiseEventImpl(
    Shell.java:308)
       at anywheresoftware.b4a.shell.Shell.raiseEvent(
    Shell.java:238)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    515)
       at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    121)
       at de.amberhome.appcompat.toolbarmenuexample.two.afterFirstLayout(two.java:
    98)
       at de.amberhome.appcompat.toolbarmenuexample.two.access$
    100(two.java:16)
       at de.amberhome.appcompat.toolbarmenuexample.two$WaitForLayout.run(two.java:
    76)
       at android.os.Handler.handleCallback(Handler.java:
    733)
       at android.os.Handler.dispatchMessage(Handler.java:
    95)
       at android.os.Looper.loop(Looper.java:
    136)
       at android.app.ActivityThread.main(ActivityThread.java:
    5001)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    785)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    601)
       at dalvik.system.NativeStart.main(Native Method)
    ** 
    Activity (two) Resume **
    but if not set toolbar.setasactionbar on 2nd activity ive got like this :
    b4a.png
    "windowActionModeOverlay" dont work on 2nd activity. and look like L theme not working.. look at the checklist still black not like on main activity
     
  14. corwin42

    corwin42 Expert Licensed User

    Your second Activity is not extended from
    android.support.v7.app.ActionBarActivity.

    All activities that use any AppCompat features have to extend ActionBarActivity so add the following to your second Activity:

    Code:
    #Extends: android.support.v7.app.ActionBarActivity
     
    DroidLyon, lemonisdead and nadhiras like this.
  15. nadhiras

    nadhiras Member Licensed User


    It Works!...
    Thanks Again Corwin...
     
  16. TheSketchees

    TheSketchees Member Licensed User

    For some reason #AdditionalRes: ..\resource doesnt exist accoring to the builder. If i remove this it will just freeze on startup??
     
  17. Peter Simpson

    Peter Simpson Expert Licensed User

    You need to make sure that you actually have a folder called resources in your root directory...
     
  18. TheSketchees

    TheSketchees Member Licensed User

    Yeah i have its working now. But still freezes at startup with no error in the logs :/ I have all files, themes. Don't know why its not working
     
    Last edited: Feb 5, 2015
  19. shashkiranr

    shashkiranr Active Member Licensed User

    Hi Corwin,

    Somtimes i get the requestfeature error. See below.

    Code:
    ActionBar Height: 56


    ** 
    Activity (test) Resume **


    Drawer Opened:


    Drawer Closed:


    MenuItem Overflow1 selected


    MenuItem Refresh selected


    MenuItem Plus one selected


    ** 
    Activity (test) Pause, UserClosed = false **


    java.lang.RuntimeException: Unable 
    to start activity ComponentInfo{de.amberhome.appcompat.toolbarexample1/de.amberhome.appcompat.toolbarexample1.addcreditcard}: android.util.AndroidRuntimeException: requestFeature() must be called before adding content


        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
        at android.app.ActivityThread.access$900(ActivityThread.java:175)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:146)
        at android.app.ActivityThread.main(ActivityThread.java:5602)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
        at dalvik.system.NativeStart.main(Native Method)
    Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
        at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:325)
        at de.amberhome.appcompat.toolbarexample1.addcreditcard.onCreate(addcreditcard.java:50)
        at android.app.Activity.performCreate(Activity.java:5451)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
        ... 11 more
    Regards,
    SK
     
  20. corwin42

    corwin42 Expert Licensed User

    Can you attach the code of your addcreditcard Activity?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice