Android Question [SOLVED]How to show the overflow menu from code? [as simulating a click event]

AscySoft

Active Member
Licensed User
Longtime User
It appear this solution is not a complet one. I implement this on an appCompat app for testing like in first post
B4X:
Sub Activity_KeyPress (KeyCode As Int) As Boolean 'Return True to consume the event
    If KeyCode= KeyCodes.KEYCODE_MENU Then
        Dim jo As JavaObject=ToolBar
        jo.RunMethod("showOverflowMenu",Null)
'ToolBar was renamed from ACToolBarLight1 in my case
        Return True
    End If
    Return False
End Sub
I have a Samsung note 3 device (with a hardware menu key)
First time when I click on menu key, overflow menu is showing as expected. But after I close it, and try this again and again it seems that is does not apear any more. From 10 consecutive menu key tapping, only a few times (2 or 3) the overflow menu is showing/hiding as expecting.

I installed another app from playstore that hase the same "hack" and I pressed menu key several times. Every time this toggle the overflow menu like it shoud with no exception.
So I gues this is not yet [perfectly] solved? Does this command only try to open overflow menu and not to close it if it's open?
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
The menu will open automatically when the user clicks on the menu button.
Of course is showing, but on the bottom left part of the screen instead on the top right.
Why is this code needed at all?
Let's just say this is what I like best (and not let anyone including google decide what is standard and non standard - in this case at least).
As I said, there are other apps as well having this "trick" working as desired.
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
I did change it back to 14, but the issue is happening nonetheless. So I guess it does not matter what targeted sdk is, the issue is there.
Further info: when I click on the toolbar menu (three dots) and the overflow menu is shown, then every time i press the hardware menu key it close it. Every time no exception. This is perfect! The opposite is not quite the same. When i press hardware menu key, some times it does nothing, sometimes it show the overflow menu but very quickly it hide it back, and only a few times it show the overflow menu without problem. Is just like triggering show/hide almost instantly(but I only press it once), with a few exceptions("normal cases").
Maybe this code is not foolproof. Is there a code (hack) to trick the system into thinking there is no hardware menu key? Will this be a better aproach? I am lost...(well...not quite...but...)
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
Can you post a screenshot of the menu coming from the bottom of the screen?
There is no menu coming from the bottom. I did apply the code you reccomend. Without it, there will be a normal menu on the bottom left corner... The overflow menu is some time showing/many times not showing, only on the upper right corner. But with issues describe above. Do you still need pictures?
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
I made two pictures. Without "jo.RunMethod("showOverflowMenu",Null)" and with it. Manifest editor is targeting sdk 14.
In the first one you could see menu from below,the second one, menu as expected. The issue whit this code was well explained above, I will not repeat myself.
Screenshot_2017-07-09-22-29-02.jpg Screenshot_2017-07-09-22-29-54.jpg
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
Further info. I unfiltered my logs. See below
Get MotionRecognitionManager
Attempted to finish an input event but the input event receiver has already been disposed.
sendUserActionEvent() mView == null
Get MotionRecognitionManager
Attempted to finish an input event but the input event receiver has already been disposed.
sendUserActionEvent() mView == null
sendUserActionEvent() mView == null
Get MotionRecognitionManager​
Explanations: when I click HWD menu key a call to "Get MotionRecognitionManager" is performed. Every time this call return "Attempted to finish an input event but the input event receiver has already been disposed" and "sendUserActionEvent() mView == null" the overflow menu is not showing. But there are times that it does display and the call to "Get MotionRecognitionManager" is not follow by any other error/log. I seems that something is wrong.
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Can you try to execute the action with CallSubDelayed instead of directly?
B4X:
Sub ShowOverflow
      Dim jo AsJavaObject=ToolBar
      jo.RunMethod("showOverflowMenu",Null) 'ToolBar was renamed from ACToolBarLight1 in my case
End Sub

Sub Activity_KeyPress (KeyCode As Int) As Boolean 'Return True to consume the event
   If KeyCode= KeyCodes.KEYCODE_MENU Then
      CallSubDelayed(Me,"ShowOverflow")
      Return True
   End If 
   Return False
End Sub

If not, please post a complete example and I will test it in my old Galaxy S3 which also has a hardware menu key
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
If you click the menu key very fast, it always works (at least in my S3). If you do it slower, it seems that the event is replicated and passed to the new view because it is being shown before the key is released (that was the purpose of CallSubDelayed, but doesn't work because the menu is anyway shown before the key is released) .
So the fact is that the menu always appears but closes at the same time because of this reason (at least in my S3). In other phones perhaps it isn't even 'seen' but the reason is the same: it is open and closed at the same time because they are consuming the same event twice ( keypress)

I solved it doing this. The event won't be replicated to the new view since KeyUp is unique
B4X:
Sub Activity_KeyUp (KeyCode As Int) As Boolean
   If KeyCode= KeyCodes.KEYCODE_MENU Then
     CallSubDelayed(Me,"ShowOverflow")     ' In fact it shouldn't be needed anymore, but I find it cleaner.
     Return True
   End If
   Return False
End Sub
 
Upvote 0

AscySoft

Active Member
Licensed User
Longtime User
That did it! I can confirm this is working well. Thanks to all of you for you support.
PS: I even put a sub on a code module and call it with a normal call, without delay, and is working as expected.
Example:
B4X:
Public Sub ShowOverflowMenu(ToolBarLight As ACToolBarLight, ToolBarDark As ACToolBarDark) As Boolean
    Try
        Dim jo As JavaObject
        If ToolBarLight.IsInitialized Then jo=ToolBarLight
        If ToolBarDark.IsInitialized Then jo=ToolBarDark
        jo.RunMethod("showOverflowMenu",Null)
        Return True
    Catch
        MsgboxAsync ("Eroare Tools.ShowOverflowMenu: " & LastException.Message,"")
        Return False
    End Try
End Sub
and the call to it is like this:
B4X:
Sub Activity_KeyUp (KeyCode As Int) As Boolean 'Return True to consume the event
    If KeyCode= KeyCodes.KEYCODE_MENU Then
        Tools.ShowOverflowMenu(ToolBar,Null)'second parameter is if theme is dark...make first null
         Return True
    End If
    Return False
End Sub
 
Upvote 0
Top