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,637
  • Screenshot_2013-08-24-12-05-45.png
    Screenshot_2013-08-24-12-05-45.png
    166.1 KB · Views: 2,666
  • Screenshot_2013-08-24-12-05-17.png
    Screenshot_2013-08-24-12-05-17.png
    203.5 KB · Views: 2,482
  • ActionDrawer Demo.zip
    47.7 KB · Views: 1,351
Last edited:

alexwekell

Member
Licensed User
Longtime User
Why do I get this error when opening the drawer?

java.lang.Exception: Sub drawer_drawerslide signature does not match expected signature.

(this is in the demo)
 

laforge

New Member
Licensed User
Longtime User
Why do I get this error when opening the drawer?

java.lang.Exception: Sub drawer_drawerslide signature does not match expected signature.

(this is in the demo)

I'll take a stab at this - this library makes use of Corwin42's excellent AHNavigationDrawer library and recently that library changed. Over in that thread Corwin42 writes in the 1.1 version release notes: "WARNING: Signature of the event subs have changed!", but I don't believe this library has yet been modified to play nicely with the new of AHNavigationDrawer that I'm guessing you have downloaded (as I did).

If you want to use the 1.1 version of AHNavigationDrawer library you need to make a couple of simple changes to this ActionDrawer class so that the drawer_drawerslide, drawer_drawerOpened and drawer_drawerClosed subs are accepting the correct number of parameters. Open up the actiondrawer sample project and the ActionDrawer class and scroll down to line 796. Change

B4X:
Private Sub Drawer_DrawerSlide (Position As Float)
to
B4X:
Private Sub Drawer_DrawerSlide (Position As Float, DrawerGravity as Int)

on line 826change

B4X:
Private Sub Drawer_DrawerClosed

to

B4X:
Private Sub Drawer_DrawerClosed (DrawerGravity as Int)

on line 845 change

B4X:
Private Sub Drawer_DrawerOpened

to

B4X:
Private Sub Drawer_DrawerOpened (DrawerGravity as Int)


If you want to double check AHNavigationDrawer.xml from the AHNavigationDrawer library you'll see that this is the correct parameters the equivalent subs require. I _think_ that is all the changes that need to be made, at the very least it clears up my errors.


I suspect either edgeryder1000 will be along shortly to update the Sample or more knowledgable B4A users will be along to correct me :) Hope that helps.
 
D

Deleted member 30048

Guest
Hello, I have a problem with this class. If I create a second activity with a new action bar and I press a button on the action bar of the second activity, return to the first activity. Why?

Thanks!
 
D

Deleted member 30048

Guest
I have the same problem. The sub is called in the Main activity whereas the actionbar is in another activity.

Well, I found a solution for this problem. The problem is that the class uses a lot of CallSubDelayed that calls to Main Activity.

The solution is declare in Process_Globals the variable "Dim ActivityName as String" and, in the "Activity_Create" of every activity, you have to give the value to the variable as the name of the activity. For example: Main.ActivityName = "Activity2"

Later you have to change all "callsubdelayed(Main,....)" in the class to "callsubdelayed(Main.ActivityName,...)"
 

andrewj

Active Member
Licensed User
Longtime User
Hi,
Can you help, please? The demo runs OK for me, but when I try to add the class to my own project, I get the following error at line 790 in your class:

Error occurred on line: 790 (actiondrawer)
java.lang.NoSuchFieldException: ic_overflow_white​

What I've noticed is that in your example, package is set to "actn.dwr" and in my code it's set to "b4a.example". Do I need to do something to install the required resources into my project?
Thanks
Andrew
 

andrewj

Active Member
Licensed User
Longtime User
Hi,
I think I've solved this myself. Changing the package name and cleaning the project seems to have sorted things out.

I manually copied the extra drawables files from the example to my project. is that the correct process?
Andrew
 

jcesar

Active Member
Licensed User
Longtime User
Thanks for this great class.

When i load a layout into action drawer activity, this activity does not have the focus, so i cant acess the activity views.
 

luke2012

Well-Known Member
Licensed User
Longtime User
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

View attachment 19078

Outstanding work! My compliments!

Which is the method to add menu entries in the nav drawer ?

http://www.b4x.com/android/forum/attachments/screenshot_2013-08-24-12-05-32-png.19078/
 

luke2012

Well-Known Member
Licensed User
Longtime User
SOLVED : with the correct android-support-v4.jar

@edgeryder1000
First of all my compliments! Outstanding work!
I'm using the Class within a multi activity app but I see that the Class link to Main in order to call events.

I'm planning to make some amendments in order to allow the class to link the "parent" activity events.
For example :

CallSub2(Main, "Overflow_Click", str.Trim) ---> We can pass the current* module name insted of "Main" ?

*For current module I mean the module that initialize the Class

N.B.
Actually if you call an event within an activity that is different from the "Main" you got an error "Sub myevent_Click not found..."
 
Last edited:

korn

Member
Licensed User
Longtime User
thanks for wonderful class wrapper.

is it possible to copy actionbar object in different activity.

like if i create actionbar with drawer in main activity. can i clone same action bar with drawer in other activity without adding views of drawer again.
 

Russ

Member
Licensed User
Longtime User
Hello,

That's very much for this. I'm struggling a bit at the moment though, I fixed that I had forgotten to include the res folders but now I have this

B4X:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
An error occurred:
(Line: 147) AD.DrawerPanel.AddView(lInfo, 4dip, 0, AD.DrawerPanel.Width, 100dip)
java.lang.NullPointerException
(Intent) Intent { act=android.intent.action.MAIN flg=0x20000000 cmp=Something.B4AExample/.main }
no extras
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
An error occurred:
(Line: 255) NavDrawer.ShadowDrawable = GetDrawable("drawer_shadow")
java.lang.NullPointerException
(Intent) Intent { act=android.intent.action.MAIN flg=0x20000000 cmp=Something.B4AExample/.main }
no extras

Any ideas please? I thought it may be a conflict with my existing code but the demo just crashes out without logging anything.

Thank you
 
Last edited:

Russ

Member
Licensed User
Longtime User
Thank you Corwin.

This is from the ActionDrawer demo

B4X:
LogCat connected to: B4A-Bridge: samsung SM-N9005-359093055278529
--------- beginning of /dev/log/main
ignoring event: updateip
ignoring event: updateip
Parent view is not a TextView
** Activity (main) Create, isFirst = false **
running waiting messages (5)
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
GC_CONCURRENT freed 1655K, 28% free 19109K/26212K, paused 8ms+2ms, total 64ms
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
    at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:545)
    at libcore.io.IoBridge.recvfrom(IoBridge.java:509)
    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:489)
    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:241)
    at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.readNumberOfBytes(AsyncStreams.java:272)
    at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.run(AsyncStreams.java:198)
    at java.lang.Thread.run(Thread.java:841)
Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
    at libcore.io.Posix.recvfromBytes(Native Method)
    at libcore.io.Posix.recvfrom(Posix.java:141)
    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
    at libcore.io.IoBridge.recvfrom(IoBridge.java:506)
    ... 6 more
libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
** Activity (main) Pause, UserClosed = false **
getExtractedText on inactive InputConnection
getTextBeforeCursor on inactive InputConnection
getSelectedText on inactive InputConnection
getTextAfterCursor on inactive InputConnection
getExtractedText on inactive InputConnection
getTextBeforeCursor on inactive InputConnection
getSelectedText on inactive InputConnection
getTextAfterCursor on inactive InputConnection
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:actn.drwr
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **

It doesn't seem to be much help. I've got an up to date Galaxy Note 3 as the handset which this is crashing on. If it's used at all I may however have issues with the Android SDK as I couldn't be sure it's up to date, installed in the correct location etc. My B4A is the latest.

I don't think I did anything to the demo beyond download and run it.

Thank you
 

alexwekell

Member
Licensed User
Longtime User
How do I get my designer script to work with this? It works regularly with Activity.Loadlayout, but if I use ad.pcontent.loadlayout then my script doesn't work correctly?

B4X:
'All variants script
'AutoScaleAll 'uncomment to scale all views based on the device physical size.
Topcard.Width = 100%x-20dip
Topcard.Left = 10dip
Topcard.Height = 40%y
Topcard.Top = 10dip

mapback.Left = 20dip
mapback.Width = 100%x-40dip
mapback.Height = Topcard.Height/1.5
mapback.Bottom = Topcard.Bottom - 10dip

card1.Top = Topcard.Bottom + 10dip
card1.Width = 100%x-20dip
card1.Left = 10dip
card1.Height = 15%y

card2.Top = card1.Bottom + 10dip
card2.Width = 100%x-20dip
card2.Left = 10dip
card2.Height = 15%y

card3.Top = card2.Bottom + 10dip
card3.Width = 100%x-20dip
card3.Left = 10dip
card3.Height = 15%y

medical.Left = card1.Left
medical.Top = card1.Top
medical.Height = card1.Height
medical.Width = card1.Height

fire.Left = card2.Left
fire.Top = card2.Top
fire.Height = card2.Height
fire.Width = card2.Height

police.Left = card3.Left
police.Top = card3.Top
police.Height = card3.Height
police.Width = card3.Height

country.Left = mapback.Left
country.Top = Topcard.Top+10dip
country.Height = Topcard.Height-mapback.Height-30dip
country.Width = mapback.Width/1.3

flag.Left = country.right+10dip
flag.Height = country.Height
flag.Top = country.top
flag.Width = mapback.Width-country.Width-10dip

call1.Top = card1.Top+10dip
call1.Height = card1.Height-20dip
call1.Width = card1.Height-20dip
call1.Right = card1.Right-10dip

call2.Top = card2.Top+10dip
call2.Height = card2.Height-20dip
call2.Width = card2.Height-20dip
call2.Right = card2.Right-10dip

call3.Top = card3.Top+10dip
call3.Height = card3.Height-20dip
call3.Width = card3.Height-20dip
call3.Right = card3.Right-10dip

bar1.Width = 40dip
bar1.Top = card1.Top
bar1.Height = card1.Height
bar1.Right = call1.Left

bar2.Width = 40dip
bar2.Top = card2.Top
bar2.Height = card2.Height
bar2.Right = call2.Left

bar3.Width = 40dip
bar3.Top = card3.Top
bar3.Height = card3.Height
bar3.Right = call3.Left
 

corwin42

Expert
Licensed User
Longtime User
Thank you Corwin.

This is from the ActionDrawer demo

B4X:
LogCat connected to: B4A-Bridge: samsung SM-N9005-359093055278529
--------- beginning of /dev/log/main
ignoring event: updateip
ignoring event: updateip
Parent view is not a TextView
** Activity (main) Create, isFirst = false **
running waiting messages (5)
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
GC_CONCURRENT freed 1655K, 28% free 19109K/26212K, paused 8ms+2ms, total 64ms
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
    at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:545)
    at libcore.io.IoBridge.recvfrom(IoBridge.java:509)
    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:489)
    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:241)
    at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.readNumberOfBytes(AsyncStreams.java:272)
    at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.run(AsyncStreams.java:198)
    at java.lang.Thread.run(Thread.java:841)
Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
    at libcore.io.Posix.recvfromBytes(Native Method)
    at libcore.io.Posix.recvfrom(Posix.java:141)
    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
    at libcore.io.IoBridge.recvfrom(IoBridge.java:506)
    ... 6 more
libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
** Activity (main) Pause, UserClosed = false **
getExtractedText on inactive InputConnection
getTextBeforeCursor on inactive InputConnection
getSelectedText on inactive InputConnection
getTextAfterCursor on inactive InputConnection
getExtractedText on inactive InputConnection
getTextBeforeCursor on inactive InputConnection
getSelectedText on inactive InputConnection
getTextAfterCursor on inactive InputConnection
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:actn.drwr
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **

It doesn't seem to be much help. I've got an up to date Galaxy Note 3 as the handset which this is crashing on. If it's used at all I may however have issues with the Android SDK as I couldn't be sure it's up to date, installed in the correct location etc. My B4A is the latest.

I don't think I did anything to the demo beyond download and run it.

This stack trace does not correspond to the above NullPointerException.
 

Russ

Member
Licensed User
Longtime User
Sorry Corwin, I'll try again.

B4X:
Connected to B4A-Bridge (Wifi)
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:actn.drwr
** Activity (main) Create, isFirst = true **
java.lang.NoClassDefFoundError: de.amberhome.navdrawer.DrawerLayout$ViewDragCallback
    at de.amberhome.navdrawer.DrawerLayout.<init>(DrawerLayout.java:232)
    at de.amberhome.navdrawer.DrawerLayout.<init>(DrawerLayout.java:222)
    at de.amberhome.navdrawer.DrawerLayout.<init>(DrawerLayout.java:218)
    at de.amberhome.navdrawer.NavigationDrawer.Initialize2(NavigationDrawer.java:84)
    at de.amberhome.navdrawer.NavigationDrawer.Initialize(NavigationDrawer.java:63)
    at actn.drwr.actiondrawer._initialize(actiondrawer.java:1822)
    at actn.drwr.main._activity_create(main.java:337)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at actn.drwr.main.afterFirstLayout(main.java:98)
    at actn.drwr.main.access$100(main.java:16)
    at actn.drwr.main$WaitForLayout.run(main.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:157)
    at android.app.ActivityThread.main(ActivityThread.java:5293)
    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:1265)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Resume **

Is it my ADK isn't installed properly? Thank you for your time.
 
Top