Android Tutorial Material Design 3 - Using a ToolBar as ActionBar

Homerclese

Member
Licensed User
Longtime User
This is a great toolbar, thank you corwin42! Is there a way to overlay a search field in the toolbar when the user taps a search button, as the Gmail and Google Contacts apps do?
 

divinglog

Member
Licensed User
Longtime User
This is a great toolbar, thank you corwin42! Is there a way to overlay a search field in the toolbar when the user taps a search button, as the Gmail and Google Contacts apps do?
Yes, you have to place a panel with a TextView and a ImageView (as back button) on top of the toolbar and toogle the visibility.

 
Last edited:

Homerclese

Member
Licensed User
Longtime User
Yes, you have to place a panel with a TextView and a ImageView (as back button) on top of the toolbar and toogle the visibility.

Thanks! I thought there might be some intrinsic/native way to handle this, but, other than the underscore, this looks pretty close to Google's Material apps.
 

corwin42

Expert
Licensed User
Longtime User
Thanks! I thought there might be some intrinsic/native way to handle this, but, other than the underscore, this looks pretty close to Google's Material apps.

There is a native way. See the SearchView example in the AppCompat library thread. Maybe that the example is a bit outdated (I'm currently working on a new version of AppCompat and then I will update the examples).
 

Homerclese

Member
Licensed User
Longtime User
Is there a way to make the Toolbar.Title a dropdown menu, as in the Google Calendar app where the month name, which appears in the Title position, can be tapped to drop down a menu? I know you can add a menu to the Toolbar but I am specifically wanting to make the Title into a menu. For example the "All" title, below, has a drop-down:

 
Last edited:

corwin42

Expert
Licensed User
Longtime User

Yes. You can add a Spinner to the Toolbar. Unfortunately the spinner theme is not inherited from the ToolBar theme in this case so the small triangle will probably display in the wrong color.

Edit: The next version of AppCompat will suport it better. I just added a Initialize2() method to ACSpinner which has a second parameter "Theme". So you can specify if the Spinner should appear in dark or light theme.
 
Last edited:

Anser

Well-Known Member
Licensed User
Longtime User
Hi,

In my app, on the ToolBar, the navigation via ShowUpIndicator ie the Arrow used to go back to the previous activity works only if I use Activity.LoadLayout. If I create an activity via code then the the navigation using the ShowUpIndicator is not working. Am I missing anything ?

Here is the code that I use ie (Activity,Toolbar etc created via code)

B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region
#Extends: android.support.v7.app.AppCompatActivity

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 ACToolBarDark
    Dim AC As AppCompat
    Dim ABHelper As ACActionBar

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("Layout1")

    Activity.Color=Colors.RGB(228,228,228)
    ActionBar.Initialize("ActionBar")
    Activity.AddView(ActionBar,0,0,100%x,56dip)

    ActionBar.SetAsActionBar  
    ActionBar.Title = "My Title"

    ' Set the Toolbar Shadow
    AC.SetElevation(ActionBar, 8dip)

    ABHelper.Initialize
    ABHelper.ShowUpIndicator = True
    ActionBar.InitMenuListener 'Back arrow menu button on the left side of the Toolbar is not working

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ActionBar_NavigationItemClick
    Activity.Finish
End Sub

With the same code, Instead of creating the Activity by code, If I use designer and use Actrivity.LoadLayout("LayoutFile") then it is working fine.
Code used when using Activity.LaodLAyout
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region
#Extends: android.support.v7.app.AppCompatActivity

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 ACToolBarDark
    Dim AC As AppCompat
    Dim ABHelper As ACActionBar

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("WebView")

    'Set the ToolBar (it is called ActionBar in the layout file) as the ActionBar of this activity.
    ActionBar.SetAsActionBar
    ActionBar.Title = "My Title"
    AC.SetElevation(ActionBar, 8dip)
  
    ABHelper.Initialize
    ABHelper.ShowUpIndicator = True
    ActionBar.InitMenuListener 'If this is not added then the Back button on the left side of the Toolbar is not working  

    WebView1.LoadUrl("http://www.google.com")
    WebView1.ZoomEnabled = False

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ActionBar_NavigationItemClick
    Activity.Finish
End Sub

Is there anything that I am missing in the code to make it working when Activity is created using code.

Regards
Anser
 
Last edited:

Anser

Well-Known Member
Licensed User
Longtime User
B4X:
  ActionBar.Initialize("ActionBar")
    Activity.AddView(ActionBar,0,0,100%x,56dip)
is missing in the second code.
The second code is using Designer and it is working fine. The problem is in the first code. I have problem only when the activity and actionbar etc created via code
 

corwin42

Expert
Licensed User
Longtime User
The proper way to add custom views is with the designer.

But it should work with adding the View by code (the ToolBar is designed for it). I will have a look on it.

In the past there was another strange effect that the Elevation did not work for the ToolBar if it was added by code. I don't know if it is still a problem.
Sometimes there are bugs in the support libraries, too and then you don't know if you have done something wrong in the wrapper.
 

JohnC

Expert
Licensed User
Longtime User
I am running into a weird problem.

I am using the light material theme:

B4X:
SetApplicationAttribute(android:theme, "@style/MyAppTheme")
CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#0098FF</item>
        <item name="colorPrimaryDark">#007CF5</item>
        <item name="colorAccent">#00AAAA</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
    </style>
</resources>)

And as you can see, the app title is in white:



But you can also see that the menu/overflow dots are in black.

And if I click the 3 dots/menu, the menu background is properly a light/white background:



If I instead change the theme to dark, then the menu dots will be white, but the menu background will then be black, which I don't want.

How can I get the menu dots to be white and the menu background to also be light/white?
 

corwin42

Expert
Licensed User
Longtime User
What you want is a light theme with a dark toolbar.

Do the following:

  1. Use Theme.AppCompat.Light.DarkActionBar as your parent theme. You don't need to use a NoActionBar theme because this is done with the windowActionBar:false item.
  2. Use ACToolBarDark as your Toolbar
  3. Set your Toolbar.PopupTheme to Light.
If you use the designer to add your Toolbar (the recommended method now) then it doesn't matter if you use a light or dark toolbar. You can set the Toolbar Theme and Popup Theme in the designer properties.
 

Anser

Well-Known Member
Licensed User
Longtime User
If you use the designer to add your Toolbar (the recommended method now) then it doesn't matter if you use a light or dark toolbar. You can set the Toolbar Theme and Popup Theme in the designer properties.

The question is asked just to clear the ambiguity and to make it more clearer

Based on the previous B4A versions and the earlier versions of AppCompat examples, I am maintaining a resource folder inside my Project Folder. Inside the resource folder there is a file named themes.xml ie \Projects\resource\values\themes.xml
It is here in this themes.xml file that I am mentioning the color themes applicable to my App

B4X:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">#418BEA</item>
        <item name="colorPrimaryDark">#2C7FE8</item>
        <item name="colorAccent">#5698EC</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
    </style>
</resources>

And in the Manifest I add the below given entry.
B4X:
'Manifest Entry for AppCompat Theme available in resource\values\theme.xml as read only
SetApplicationAttribute(android:theme, "@style/MyAppTheme")
'End of lines required for AppCompat

The question is asked just to clear the ambiguity and to make it more clearer.

To use AppCompat in my app, do I still need all the above ie the Manifest entry and the resource folder ? With B4A 6 and the latest version of AppCompat, can I choose
  • The Color (backcolor) applicable for the Toolbar,
  • The color of the Text on the ToolBar ie the Title and SubTitle,
  • The background color of the PopUp menu on the ToolBar ie whether it should be white OR DarkGrey etc
  • The Text color of the PopupMenu on the ToolBar
from the Designer itself ?

If the above is possible then I believe that I can have different colors for the ToolBar in different activities in the same App.

Regards

Anser
 
Last edited:

Haris Hafeez

Active Member
Licensed User
Longtime User
Hello All,
[RESOLVED] - I just created a new layout that is exactly the same as the one I was using previously and the problem has gone away! I am not a fan of magic happening while developing but I'll accept it over frustrating NPEs.

After updating the Android SDK, I am struggling to a previously working app to work. The app crashes upon launch with the following stacktrace:
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
main_activity_create (java line: 548)
java.lang.RuntimeException: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Object.equals(java.lang.Object)' on a null object reference
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:166)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at com.impactmotor.app.main._activity_create(main.java:548)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at com.impactmotor.app.main.afterFirstLayout(main.java:102)
at com.impactmotor.app.main.access$000(main.java:17)
at com.impactmotor.app.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Object.equals(java.lang.Object)' on a null object reference
at de.amberhome.objects.appcompat.ACToolBarWrapper.DesignerCreateView(ACToolBarWrapper.java:74)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:70)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:158)
... 16 more
** Service (starter) Create **
** Service (starter) Start **
** Service (firebasemessaging) Create **
** Service (firebasemessaging) Start **

Unfortunately, I cannot identify which part is causing this, only that I can see that the app crashes straight after trying to load the main layout that contains ACToolbarDark. This is the same layout as in the example, the one that contains the toolbar custom view and a panel. Any ideas why this might be causing it?

I have tried extending the activity using both ActionBarActivity and AppCompatActivity with the same result.

The SDK details are:


 
Last edited:

corwin42

Expert
Licensed User
Longtime User
Short answer: Yes.

Long answer: The only thing you ever needed to do is to extend your activities from AppCompatActivity and set a AppCompat theme in the manifest editor.

The additional theme was only necessary to set the primary, primaryDark and accent colors. And if you use a ToolBar it is better to use a Theme which includes an ActionBar and then disable it in the theme.


All the above settings were possible in the previous version, too. Even different colors for the ToolBar was (and is) still possible with different themes for different Activites. Just set individual themes for your activities in the manifest editor.
 

corwin42

Expert
Licensed User
Longtime User
Hello All,
[RESOLVED] - I just created a new layout that is exactly the same as the one I was using previously and the problem has gone away! I am not a fan of magic happening while developing but I'll accept it over frustrating NPEs.

The answer is simple. It would have been enough to just enter the designer and save your layouts.

The problem was that the new library is trying to access the new custom designer properties. These properties are missing in the old designer files and this is the cause for the NullPointerExceptions. Just saving the layout again will include the properties in the layout files an everything will be fine.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…