B4A Class ActionDrawer - ActionBar and NavDrawer Made Perfect

ActionDrawer is a combination of my own custom actionbar class and the native navigation drawer. It aims to be an extremely simple way for basic4android users to make quality apps which follow google's guidlines, while still allowing lots of customization.
Features include: Dark and light themes, dynamic fitting of the action buttons to the overflow menu(try rotating the demo app), the drawer and up indicators, and more.
ActionDrawer requires AHNavigationDrawer, the reflection library, and the drawables in the zip below.

NOTE: For version 2.0 I will be rewriting this class to make it more flexible and simple, and also adding some big features like pull to refresh, multiple navdrawers, and making it easier to add nice lists to the drawer. v2.0 will be incompatible with the current version, so you may want to wait instead of using the current class.

Update v1.01
- Fixed a bug where double-tapping and holding the home button would cause it to stay selected
v1.1
- Added tooltips! When the actionbar buttons are long-pressed a special toast message will be displayed
- fixed a title-shortening bug
v1.2
-Changed how click events work (you now specify the eventname when adding the button) as suggested by corwin42. This means that v1.2 is not fully compatible with previous versions
v1.21
-Made SectionTitle (string) and lTitle (label) public. Now you can change the actionbar title however you want

Screenshot_2013-08-24-12-05-32.png
 

Attachments

  • Screenshot_2013-08-24-12-06-03.png
    Screenshot_2013-08-24-12-06-03.png
    195.7 KB · Views: 2,442
  • Screenshot_2013-08-24-12-05-45.png
    Screenshot_2013-08-24-12-05-45.png
    166.1 KB · Views: 2,462
  • Screenshot_2013-08-24-12-05-17.png
    Screenshot_2013-08-24-12-05-17.png
    203.5 KB · Views: 2,292
  • ActionDrawer Demo.zip
    47.7 KB · Views: 1,152
Last edited:

edgeryder1000

Member
Licensed User
The following code should work:
B4X:
Dim ListView1 As ListView
    ListView1.Initialize("")
    ListView1.AddSingleLine("Line1")
    ListView1.AddSingleLine("Line2")
    AD.DrawerPanel.AddView(ListView1, 0dip, 0dip, AD.DrawerPanel.Width, AD.DrawerPanel.Height)

If you want the last clicked list item to stay highlighted (like it does in most navigation drawers) then you should have a look at mlistview
 

deltacode

Member
Licensed User
Quick one, how can i change an icon of the actionbar.

e.g. i have a icon of a number 1 and the user presses it, it gets replaced with a number 2 icon.

Can this be done quickly and easily ?
 

edgeryder1000

Member
Licensed User
The best way would be to add a sub to the class:
B4X:
Public Sub ChangeIcon(NewIcon As String)
    iIcon.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
    iIcon.Gravity = Gravity.FILL
End Sub
and call AD.ChangeIcon("Icon2.png")
 

deltacode

Member
Licensed User
Thanks for the reply, how can i tell which action this icon is replacing ?

I've added two actions as icons to the action bar and need to only change one of the icons when the action is pressed.
 

edgeryder1000

Member
Licensed User
Ah, I though you meant the application icon in the top-left corner. To change an action's icon you will need to know its position from the right. So the first action you add will have a position of 1, and the next will have a position of 2. Here is the code:
B4X:
Public Sub ChangeIcon(NewIcon As String, Position As Int)
    Select Position
        Case 1
            iAction1.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
            iAction1.Gravity = Gravity.FILL
        Case 2
            iAction2.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
            iAction2.Gravity = Gravity.FILL
        Case 3
            iAction1.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
            iAction1.Gravity = Gravity.FILL
        Case 4
            iAction2.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
            iAction2.Gravity = Gravity.FILL
        Case 5
            iAction1.SetBackgroundImage(LoadBitmap(File.DirAssets, NewIcon))
            iAction1.Gravity = Gravity.FILL
    End Select
End Sub
 

deltacode

Member
Licensed User
Thanks for this answer, i was trying to make it far more complicated by finding the view and trying to remove it.

I like simple solutions :)
 

Inman

Well-Known Member
Licensed User
Now that AHNavigationDrawer has been updated, could you please add support for 2 nav drawers (left and right)? Also will it be possible for you to add the official Swipe-to-Refresh gesture? It is sort of like iOS's pull-to-refresh gesture. You can see it in the official Google apps like Gmail, G+, Drive etc..
 

Inman

Well-Known Member
Licensed User
I would like to change the title text of the actionbar, based on the item selected in navigationdrawer. I see that there is an actiondrawer.apptitle parameter but it is used only when the navdrawer is opened. Shouldn't it be used when the navdrawer is closed, so that the actionbar title can be changed dynamically?

Since it is a class module, I can modify the code myself to fix this. I just wanted to inform you this so that you can fix it in the next version of the class.
 

edgeryder1000

Member
Licensed User
I would like to change the title text of the actionbar, based on the item selected in navigationdrawer. I see that there is an actiondrawer.apptitle parameter but it is used only when the navdrawer is opened. Shouldn't it be used when the navdrawer is closed, so that the actionbar title can be changed dynamically?

Since it is a class module, I can modify the code myself to fix this. I just wanted to inform you this so that you can fix it in the next version of the class.

I will add this in when I get home.

Now that AHNavigationDrawer has been updated, could you please add support for 2 nav drawers (left and right)? Also will it be possible for you to add the official Swipe-to-Refresh gesture? It is sort of like iOS's pull-to-refresh gesture. You can see it in the official Google apps like Gmail, G+, Drive etc..

Yep, version 2.0 will include multiple drawers and pull-to-refresh. It won't be the official pull to refresh (haven't learned java yet), but I'll try my best to copy it accurately. I won't have much free time in the next few weeks since I need to study for exams, but after that I'll start working on it.
Maybe there'll be some new stuff in android 4.4 that can be added in too :)
 

Inman

Well-Known Member
Licensed User
Thanks man. Sounds great.

I noticed another issue. In your class, you raise the events that need to be send back to initiating module, as CallSubDelayed(Main, Event1). This would mean that the event gets raised only in the Main activity, which may not always be the activity to which the actiondrawer is added.

Another suggestion is the option to disable the overflow menu completely. In Ad.initialize(), in place of the overflowitems list parameter, the developer could send Null. In your class, you could check if the overflowitems list is initialized and if it is not, you could avoid overflow menu.

All the best for your exams.
 

edgeryder1000

Member
Licensed User
I noticed another issue. In your class, you raise the events that need to be send back to initiating module, as CallSubDelayed(Main, Event1). This would mean that the event gets raised only in the Main activity, which may not always be the activity to which the actiondrawer is added.
Thanks for reminding me about that, I'll fix it when I'm updating everything else. Almost everything will be re-written, so i was thinking of writing the class to be more modular, e.g. AD.Init(Module), AD.AddOverflow(List), AD.AddDrawer(Side, Width, Color)...
All the best for your exams
Thanks :)
 

deltacode

Member
Licensed User
Quick question

How can i remove an overflow item from the list, i tried adding this to the class and calling it but it did not do remove any item:

B4X:
Public Sub RemoveOverFlow(Position As Int)
    OverflowList.RemoveAt(Position)
End Sub
 

edgeryder1000

Member
Licensed User
Quick question

How can i remove an overflow item from the list, i tried adding this to the class and calling it but it did not do remove any item:

B4X:
Public Sub RemoveOverFlow(Position As Int)
    OverflowList.RemoveAt(Position)
End Sub
The overflow menu is actually a spinner (named sOverflow). The code you need is
B4X:
Public Sub RemoveOverFlow(Position As Int)
    sOverflow.RemoveAt(Position)
End Sub
Hopefully that works
 

deltacode

Member
Licensed User
thanks a lot for the quick response, was about to delete my question as i worked it out but hopefully this will be helpful for others :)
 

ciprian

Active Member
Licensed User
Hi there. How can i hide a view into the drawer?
I have created a view like ...
B4X:
AD.AddAction("Anim", "t0.png")
How can i hide it when i need to?

I was thinking of something like...
B4X:
AD.RemoveAt("id")
But... :)
Any sugestions?
 

akion

New Member
Licensed User
I'm not exactly sure what you mean, but if you just want to hide actions (for example when the drawer is opened) the following might work:
B4X:
Public Sub RemoveAction(Position As Int)
    Select Position
        Case 1
            iAction1.RemoveView
            pAction1.RemoveView
        Case 2
            iAction2.RemoveView
            pAction2.RemoveView
        Case 3
            iAction3.RemoveView
            pAction3.RemoveView       
        Case 4
            iAction4.RemoveView
            pAction4.RemoveView
        Case 5
            iAction5.RemoveView
            pAction5.RemoveView
    End Select
    Title_Resize
End Sub
 
Top