B4A Library [Class] SlideMenu

This is a class that implements a sliding menu as seen in many apps like Google+, Evernote, Facebook etc.

Requires B4A 2.0 or newer.
 

Attachments

  • SlideMenuClass_1_0.zip
    12.6 KB · Views: 5,008
  • screenshot-1340094419260.png
    screenshot-1340094419260.png
    32.3 KB · Views: 6,267

GMan

Well-Known Member
Licensed User
Longtime User
full and improved addItem Sub

I fixed some of the calculations and make it grow from the bottom up (comment the ...top part if you do not want it like that:
B4X:
Public Sub AddItem(Text As String, Image As Bitmap, ReturnValue As Object)
   Dim item As ActionItem
   item.Initialize
   item.Text = Text
   item.Image = Image
   item.Value = ReturnValue

   If Not(Image.IsInitialized) Then
      mListView.AddTwoLinesAndBitmap2(Text, "", Null, ReturnValue)
   Else
      mListView.AddTwoLinesAndBitmap2(Text, "", Image, ReturnValue)
   End If
   'Log (mListView.Size & " items Hight:" & (mListView.Size * itemHeight))
         
   'mSlidePanel.Height = mListView.Size * itemHeight - 2
   'If (mSlidePanel.Height > 100%y - mSlidePanel.Top) Then mSlidePanel.Height = 100%y - mSlidePanel.Top

   mSlidePanel.Height = mListView.Size * itemHeight - 2
   If (mSlidePanel.Height > 100%y) Then mSlidePanel.Height = 100%y
   mSlidePanel.Top = 100%y-mSlidePanel.Height ' set to grow from the bottom   
   mListView.Height = mSlidePanel.Height
   'log ("width=" & mlistView.Width)
   Dim c As Canvas
   c.Initialize(mListView)
   Dim w As Int = c.MeasureStringWidth(Text,mListView.TwoLinesAndBitmap.Label.Typeface,mListView.TwoLinesAndBitmap.Label.TextSize) + mListView.TwoLinesAndBitmap.Label.Left+ 10
   'Log ("w=" & w)
   If (w>100%x) Then w = 100%x
   If (w > mSlidePanel.Width ) Then ' if smaller no need to change, leave the width as the wider of all labels
      'Log ("setting width to be:" & w)
      mSlidePanel.Width = w
      mListView.Width = w   
   End If
End Sub


you will need to add this var Private itemHeight As Int
AND ADD IT IN INIT as
itemHeight = mListView.TwoLinesAndBitmap.itemHeight + 2
Works perfect
 

GMan

Well-Known Member
Licensed User
Longtime User
full and improved addItem Sub

I fixed some of the calculations and make it grow from the bottom up (comment the ...top part if you do not want it like that:
B4X:
Public Sub AddItem(Text As String, Image As Bitmap, ReturnValue As Object)
   Dim item As ActionItem
   item.Initialize
   item.Text = Text
   item.Image = Image
   item.Value = ReturnValue
 
   If Not(Image.IsInitialized) Then
      mListView.AddTwoLinesAndBitmap2(Text, "", Null, ReturnValue)
   Else
      mListView.AddTwoLinesAndBitmap2(Text, "", Image, ReturnValue)
   End If
   'Log (mListView.Size & " items Hight:" & (mListView.Size * itemHeight))
          
   'mSlidePanel.Height = mListView.Size * itemHeight - 2
   'If (mSlidePanel.Height > 100%y - mSlidePanel.Top) Then mSlidePanel.Height = 100%y - mSlidePanel.Top

   mSlidePanel.Height = mListView.Size * itemHeight - 2 
   If (mSlidePanel.Height > 100%y) Then mSlidePanel.Height = 100%y
   mSlidePanel.Top = 100%y-mSlidePanel.Height ' set to grow from the bottom    
   mListView.Height = mSlidePanel.Height
   'log ("width=" & mlistView.Width)
   Dim c As Canvas
   c.Initialize(mListView)
   Dim w As Int = c.MeasureStringWidth(Text,mListView.TwoLinesAndBitmap.Label.Typeface,mListView.TwoLinesAndBitmap.Label.TextSize) + mListView.TwoLinesAndBitmap.Label.Left+ 10
   'Log ("w=" & w)
   If (w>100%x) Then w = 100%x
   If (w > mSlidePanel.Width ) Then ' if smaller no need to change, leave the width as the wider of all labels
      'Log ("setting width to be:" & w)
      mSlidePanel.Width = w
      mListView.Width = w    
   End If
End Sub


you will need to add this var Private itemHeight As Int
AND ADD IT IN INIT as
itemHeight = mListView.TwoLinesAndBitmap.itemHeight + 2
Works perfect
imgres

I am using the sample code:
B4X:
Private Sub mListView_ItemClick (Position As Int, Value As Object)
  Dim subname As String
  Hide
  subname = mEventName & "_Click"
  If SubExists(mModule, subname) Then
      'CallSub2(mModule, subname, Value)
      CallSubDelayed2(mModule, subname, Value)
  End If
End Sub

But nothing happens except the ToastMessage was shown.

I tried also
B4X:
If SubExists(Main, subname) Then
        ''CallSub2(Main, subname, Value)
        CallSubDelayed2(Main, subname, Value)
End If
(replace mModule with Main (where the subs are placed) but also nohting happened

If i change this in the Main it works:
B4X:
Sub SlideMenu_Click(Item As Object)
    ToastMessageShow("Item clicked: " & Item, False)
   
    If Item = "ende" Then
        ende_Click
    End If
   
End Sub
 

Shahid Saeed

Active Member
Licensed User
Longtime User
First of all thanks for this nice class: I have couple of questions:-
1- Is it possible to display the SlideMenu on the right-side and animate from right -> left as well.
2- When I am adding Arabic text (العربية) into add item it doesn't show text. Only English text is being displayed. P.N Arabic text other than SlideMenu shwoing on my APP.
 

corwin42

Expert
Licensed User
Longtime User
First of all thanks for this nice class: I have couple of questions:-
1- Is it possible to display the SlideMenu on the right-side and animate from right -> left as well.
2- When I am adding Arabic text (العربية) into add item it doesn't show text. Only English text is being displayed. P.N Arabic text other than SlideMenu shwoing on my APP.

1 - You may consider using AHNavigationDrawer library. It can handle slides from left and right.
2 - No Idea. The class uses a simple Listview I think. Have you tried Arabic text on a normal ListView in B4A?
 

Shahid Saeed

Active Member
Licensed User
Longtime User
1 - You may consider using AHNavigationDrawer library. It can handle slides from left and right.
2 - No Idea. The class uses a simple Listview I think. Have you tried Arabic text on a normal ListView in B4A?

I worked out a little bit to make the SlideMenu to show on the right side, I have also fixed the problem with Arabic Language because Arabic works right to left and the text was appearing on hidden zone I had to use the Label.Left to bring it where it should be.

Here is the code for others reference if they want to make SlideMenu appears on the Right Side and to Work with Languages Right to Left.

B4X:
Sub Initialize(Activity As Activity, Module As Object, EventName As String, Top As Int, Width As Int)
    mModule = Module
    mEventName = EventName

    mSlidePanel.Initialize("mSlidePanel")

    mListView.Initialize("mListView")
    mListView.TwoLinesAndBitmap.SecondLabel.Visible = False
    mListView.TwoLinesAndBitmap.ItemHeight = 50dip
    mListView.TwoLinesAndBitmap.ImageView.SetLayout(13dip, 13dip, 29dip, 19dip)
    mListView.TwoLinesAndBitmap.ImageView.Left = Width - 40dip
    mListView.TwoLinesAndBitmap.Label.Gravity = Gravity.CENTER_VERTICAL
    mListView.TwoLinesAndBitmap.Label.Height = mListView.TwoLinesAndBitmap.ItemHeight
    mListView.TwoLinesAndBitmap.Label.Top = 0
    mListView.TwoLinesAndBitmap.Label.Left = -45dip
    mListView.TwoLinesAndBitmap.Label.Typeface = fnc.ArFont   
    mListView.Color = Colors.RGB(148, 0, 211)   
   
    mInAnimation.InitializeTranslate("", 100%x - Width, 0, 100%x - Width, 0)
    mInAnimation.Duration = 200
    mOutAnimation.InitializeTranslate("Out", 100%x + Width, 0, 100%x + Width, 0)
    mOutAnimation.Duration = 200
   
    Activity.AddView(mSlidePanel, 0, Top, Width, 20%y - Top)
       
    mBackPanel.Initialize("mBackPanel")
    mBackPanel.Color = Colors.Transparent
    Activity.AddView(mBackPanel, 100%x, 0, -100%x, 20%y)

    mSlidePanel.AddView(mListView, 0, 0, mSlidePanel.Width, mSlidePanel.Height)
    mSlidePanel.Visible = False
End Sub

'Adds an item to the SlideMenu
' Text - Text to show in menu
' Image - Image to show
' ReturnValue - The value that will be returned in the Click event
Public Sub AddItem(Text As String, Image As Bitmap, ReturnValue As Object)
    Dim item As ActionItem
    item.Initialize
    item.Text = Text
    item.Image = Image
    item.Value = ReturnValue
   
    If Not(Image.IsInitialized) Then
        mListView.AddTwoLinesAndBitmap2(Text, "", Null, ReturnValue)
    Else
        mListView.AddTwoLinesAndBitmap2(Text, "", Image, ReturnValue)
    End If
End Sub

'Show the SlideMenu
Public Sub Show
    If isVisible = True Then Return
   
    mBackPanel.BringToFront
    mSlidePanel.BringToFront
    mBackPanel.Left = 100%x + mBackPanel.Width
    mSlidePanel.Left = 100%x - mSlidePanel.Width
   
    mSlidePanel.Visible = True
    mInAnimation.Start(mSlidePanel)
End Sub
 

BarryW

Active Member
Licensed User
Longtime User
How make backpanel alpha animation... i set the color to colors.black and i want to do alpha animation while your slidemenu opens.. And also why does your sliding menu goes back to the top after calling hide then calling show. Can i set this to fix position whenever the user close or hide the slidemenu... Tnx
 
Last edited:

sasidhar

Active Member
Licensed User
Longtime User
hi corwin,
i'm trying to implement sliding menu. so far it works properly, and it's nice.
but i found something weird.

i use sliding menu, additem about 5 or 6 items.
to get the value when user choose the menu, i use:
B4X:
Sub SlideMenu_Click(Item As Object)
    Dim ix As Int

    ix=Item

    Select Case ix
    Case 1
        'profile
        StartActivity(ProfileForm)
    Case 2
        'new
        StartActivity(NewArticle)
    Case 3
        'search
    Case 4
        'Category
    Case 5
        'About
        StartActivity(AboutUs)
    Case 6
        'logout
    
        StartActivity(LoginForm)
        Activity.Finish
    End Select
End Sub

the slide menu was working good and calls the correct action using slide or menu button. but after i got back from the called activity (pressing back to get back to this current form which has a slide menu), i can't slide the menu, i can't event call the slide menu with menu button on below. it's stopped. i have to press the power button to turn off the screen, wait for a moment (10-20 seconds), then turn the screen on again to access the slide menu.

is there anything i should type, perhaps in Activity_Resume?
here is the activity log:
B4X:
LogCat connected to: B4A-Bridge: Hisense AD683G-a1000033e86438
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
Installing file.
PackageAdded: package:rony.cerita.seru
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
startService: class anywheresoftware.b4a.samples.httputils2.httputils2service
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (menuutama) Create, isFirst = true **
** Activity (menuutama) Resume **
** Activity (menuutama) Pause, UserClosed = false **
** Activity (profileform) Create, isFirst = true **
** Activity (profileform) Resume **
** Activity (profileform) Pause, UserClosed = true **
** Activity (menuutama) Resume **
** Activity (menuutama) Pause, UserClosed = false **
** Activity (menuutama) Resume **
** Activity (menuutama) Pause, UserClosed = false **

profileform has a slidemenu and it is called from menuutama using slidemenu.
profileform has never failed but menuutama will hang for a while then it works again.

something wrong with slidemenu when Resume event is raised.

thanks :)


Hi,

I have few designer forms similar to the above, on click menu item how to add layout.bal
using activity.loadlayout("layout") gives error.

please help.

thanks
 

sasidhar

Active Member
Licensed User
Longtime User
Hi,

I have few designer Layouts similar to the above, on click menu item how to add layout.bal
using activity.loadlayout("layout") gives error.

please help.

thanks
 

Devv

Active Member
Licensed User
Longtime User
Perfect , that was exactly what i was searching for
thanks a lot.
 

Devv

Active Member
Licensed User
Longtime User
i suggest to edit this is in the class
to solve the unexpected unshowing of the menu in some cases

B4X:
Public Sub Hide(animated As Boolean)
    If isVisible = False Then Return
   
    If animated = True Then
        mOutAnimation.Duration = 200
    Else
        mOutAnimation.Duration = 0
    End If
   
    mBackPanel.Left = -mBackPanel.Width
    mSlidePanel.Left = -mSlidePanel.Width
   
    mOutAnimation.Start(mSlidePanel)
End Sub

Private Sub mBackPanel_Touch (Action As Int, X As Float, Y As Float)
    If Action = 1 Then
        Hide(True)
    End If
End Sub

Private Sub mListView_ItemClick (Position As Int, Value As Object)
    Dim subname As String
    Hide(False)
    subname = mEventName & "_Click"
    If SubExists(mModule, subname) Then
        CallSub2(mModule, subname, Value)
    End If
End Sub
 
Top