Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-1512] Android: OptionMenu is not working with TabGroup

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2013-01-23T03:33:33.000+0000
Affected Version/sRelease 3.0.0
Fix Version/sRelease 3.0.2, Release 3.1.0, 2013 Sprint 02 API, 2013 Sprint 02
ComponentsAndroid
Labelsapi, module_tabgroup, qe-review, qe-testadded, triage
ReporterBorey
AssigneeHieu Pham
Created2011-04-15T02:54:49.000+0000
Updated2013-07-19T01:45:09.000+0000

Description

I've tested Option menu with normal window, it's working fine. However I can't get it working with TabGroup. Test code:

var win1 = Ti.UI.createWindow({
    backgroundColor: 'blue',
    fullscreen: false
});
var tab1 = Ti.UI.createTab({
    window: win1,
    title: 'Tab 1'
});

var win2 = Ti.UI.createWindow({
    backgroundColor: 'yellow'
});
var tab2 = Ti.UI.createTab({
    window: win2,
    title: 'Tab 2'
});

var tabGroup = Ti.UI.createTabGroup({
	activity: {
        onCreateOptionsMenu: function(e) {
            var menu = e.menu;
            var menuItem = menu.add({
                title : "Item 1",
                itemId: 1
            });
            var menuItem2 = menu.add({
                title : "Item 2",
                itemId: 2
            });
            menuItem.addEventListener("click", function(e) {
                Ti.API.info("Item1 was clicked");
            });
            menuItem2.addEventListener("click", function(e) {
                Ti.API.info("Item2 was clicked");
            });
        },
        
        onPrepareOptionsMenu: function(e) {
        	var menu = e.menu;
        	if (tab1.active) {
        		menu.findItem(1).setVisible(false);
        		menu.findItem(2).setVisible(true);
        	}
        	
        	if (tab2.active) {
        		menu.findItem(1).setVisible(true);
        		menu.findItem(2).setVisible(false);
        	}
        }
    }
});
  
tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
tabGroup.open();

1. Click on menu/optionMenu button, should see "Item 2" in tab1 and "Item 1" in tab2.

Attachments

FileDateSize
app.js2011-04-15T02:54:50.000+00001773

Comments

  1. Borey 2011-04-15

    it's been 2 months, and there's no reply to this ticket. Just wonder if anyone has checked it.

  2. Andrew Heebner 2011-04-15

    Read the docs closer. Option menus are meant for windows, not tabs. Menus are created on a per-window basis, but you can also recycle the menu by simply adding it to any window "open" event....

    Stick all of your menu code in a function, then add this code.

       win1.addEventListener('open', function(e) {
           // add the menu here.
           addMenuToWindow();
       });
       

    Now (theoretically), when you switch tabs, the window also changes. You need to adjust accordingly for the UI layouts. This is not a bug, it is intended proper usage.

  3. Stephen Tramer 2011-04-15

    Assigning to Don for triage.

  4. Junaid Younus 2012-08-15

    The existing app.js isn't applicable anymore (the functions have been deprecated), here is some quick code I put together:
       var win = Ti.UI.createWindow({fullscreen : true});
       
       var tabGroup = Ti.UI.createTabGroup();
       
       var win1 = Ti.UI.createWindow({backgroundColor: 'white'});
       var tab1 = Ti.UI.createTab({
           window: win1,
           title: 'Tab 1'
       });
       
       var win2 = Ti.UI.createWindow({backgroundColor: 'yellow'});
       var tab2 = Ti.UI.createTab({
           window: win2,
           title: 'Tab 2'
       });
       
       var activity = win.activity;
       
       activity.onCreateOptionsMenu = function(e)
       {
           var menu = e.menu;
           var menuItem = menu.add(
           {
               title : "Item 1"
           });
           menuItem.icon = "_images/play.png";
           menuItem.addEventListener("click", function(e)
           {
               Ti.API.info("I was clicked");
           });
       };
       
       tabGroup.addTab(tab1);
       tabGroup.addTab(tab2);
       
       tabGroup.open(); 
       
    Tested on a Samsung Galaxy S2 using TiSDK 2.2.0v20120814103312, doesn't look like it works. Issue still exists.
  5. Martin Guillon 2012-09-30

    I have the same issue: android 4.0.3 device / simulator Ti SDK 3.0.0 (master)
  6. Tony Lukasavage 2012-10-31

    I am experiencing the same thing in Alloy apps. Android menus work fine when created with just a heavyweight window, but they don't appear when that heavyweight window is contained in a Tab, which is in turn contained in a tabgroup.
  7. Igor Santos 2012-12-12

    I'm not sure if the sample code two comments before should even work: the win object is created but never used, and thus, will never have the event called. Although, I did tried editing onCreateOptionsMenu for the TabGroup and it's not called. I solved this adding the menu to TabGroup.activeTab.window. For me this is a workaround, and would never be a "intended usage" as stated before.
  8. Hieu Pham 2012-12-18

    The sample code is flawed. I've tested with this code and it seems to work fine with both tabgroup and action bar.
        
       var tabGroup = Ti.UI.createTabGroup();
        
       var win1 = Ti.UI.createWindow({backgroundColor: 'white'});
       var tab1 = Ti.UI.createTab({
           window: win1,
           title: 'Tab 1'
       });
        
       var win2 = Ti.UI.createWindow({backgroundColor: 'yellow'});
       var tab2 = Ti.UI.createTab({
           window: win2,
           title: 'Tab 2'
       });
        
       
        
       tabGroup.addTab(tab1);
       tabGroup.addTab(tab2);
        
       tabGroup.open(); 
       
       tabGroup.addEventListener('open', function() {
       
       var activity = win1.activity;
        
       activity.onCreateOptionsMenu = function(e)
       {
           var menu = e.menu;
           var menuItem = menu.add(
           {
               title : "Item 1"
           });
           menuItem.icon = "_images/play.png";
           menuItem.addEventListener("click", function(e)
           {
               Ti.API.info("I was clicked");
           });
       };
       });
       
       
  9. Hieu Pham 2012-12-18

    Closing bug as invalid.
  10. Igor Santos 2012-12-18

    How about my question about the tabGroup Activity? {quote} Although, I did tried editing onCreateOptionsMenu for the TabGroup and it's not called. I solved this adding the menu to TabGroup.activeTab.window. For me this is a workaround, and would never be a "intended usage" as stated before. {quote}
  11. Hieu Pham 2012-12-18

    Hi Igor, I'm not sure I understand your question completely. Can you provide sample code of your workaround?
  12. Igor Santos 2012-12-18

    The main idea is that I think it's weird to set menu for the TabGroup through one of its windows... But I'm not sure how would be the better way to solve this. Maybe all the windows' should point to the main activity, as the TabGroup?
  13. Hieu Pham 2012-12-18

    All the windows in a tab group share the same activity as the tab group itself. However, we don't expose the tab group's activity, so you'd have to get the activity from its window(s). I.e "tabgroup.activity" would be undefined while "win1.activity" will return the tab group activity.
  14. Igor Santos 2012-12-18

    Ok, you just explained what was missing in my idea. So... why couldn't the TabGroup.activity refer to the same activity in the windows? It makes much more sense in the code to change the menus for it than changing menu for one of the windows.
  15. Tony Lukasavage 2012-12-18

    @Hieu: This bug should not be closed, it still occurs. I have it happening in Alloy and I've recreated the issue in the traditional Titanium code below:
        var tabGroup = Ti.UI.createTabGroup();
          
        var win1 = Ti.UI.createWindow({
            backgroundColor: 'white',
            fullscreen: false,
            activity: {
                onCreateOptionsMenu: function(e) {
                    var menu = e.menu;
                    var menuItem = menu.add({
                        title : "Item 1"
                    });
                    menuItem.icon = "_images/play.png";
                    menuItem.addEventListener("click", function(e) {
                        Ti.API.info("I was clicked");
                    });
                }
            }
        });
        var tab1 = Ti.UI.createTab({
            window: win1,
            title: 'Tab 1'
        });
        
        tabGroup.addTab(tab1);
        tabGroup.open();  
        
    A developer should not have to add the "open" event to the tabgroup just to have the options menu show up in the Window. Developers don't need to do this in the case of just a Window. The code below works just fine:
        var win1 = Ti.UI.createWindow({
            backgroundColor: 'white',
            fullscreen: false,
            activity: {
                onCreateOptionsMenu: function(e) {
                    var menu = e.menu;
                    var menuItem = menu.add({
                        title : "Item 1"
                    });
                    menuItem.icon = "_images/play.png";
                    menuItem.addEventListener("click", function(e) {
                        Ti.API.info("I was clicked");
                		});
                	}
            }
        });
        win1.open();
        
    I should be able to use this window, as is, in a tab and make it show the options menu, but it will not unless I use the tabgroup's "open" event. I think the appropriate solution should be to for onCreateOptionsMenu to work in my first example as written, Titanium should handle using the activity's onCreateOptionsMenu at the appropriate time under the hood, with no "open" event necessary. The code you tested Hieu is a work around, but it doesn't address the root problem. At the very least this should be documented, but forcing special handling for android menus just for tabs seems silly.
  16. Hieu Pham 2012-12-18

    @Tony: https://github.com/appcelerator/titanium_mobile/pull/3619 will address this issue.
  17. Ping Wang 2012-12-26

    Tabgroup.activity is now exposed (see TIMOB-11796).
  18. Martin Guillon 2013-01-12

    I comment here to explain that i managed to have a menu by tab window (even sub windows) in a tab group. The idea is not to listen to the "open" event but to the "focus" event. Then you call something like this in the "focus" event
        function createMenu() {
        	var activity = self.activity;
        	activity.invalidateOptionsMenu();
        	activity.onCreateOptionsMenu = function(e) {
        		Ti.API.info('wanted onCreateOptionsMenu')
        		var menu = e.menu;
        		var menuItem = menu.add({
        			title : tr('Refresh', 'Refresh')
        		});
        		menuItem.addEventListener("click", self.refresh);
        	};
        }
        
  19. Igor Santos 2013-01-13

    Wow, I didn't know the invalidateOptionsMenu. That's a good workaround on this issue, I'll probably be using this in the future. Thanks!
  20. Vishal Duggal 2013-01-16

    https://github.com/appcelerator/titanium_mobile/pull/3619
  21. Hieu Pham 2013-01-16

    We will expose "activity" to tab group so you can initialize the menu there - Each tab group now supports one menu. You can, however, modify the menu's content between tabs. I've updated the test code to demonstrate this.
  22. Tony Lukasavage 2013-01-16

    @Hieu: Just to be clear, the Ti.UI.Windows inside each Tab inside a Tabgroup will *_not_* support android menus being added to them. Instead, in the case of TabGroup, developers will add the android menu to the TabGroup's activity. The android menu will apply to all Tabs and if developers want the android menu to change from tab to tab, they will have to do it in code dynamically as the tabs change focus. Is that correct?
  23. Hieu Pham 2013-01-16

    @Tony: That is correct.
  24. Vishal Duggal 2013-01-21

    Backport Task TIMOB-12335 Backport PR https://github.com/appcelerator/titanium_mobile/pull/3740
  25. Federico Casali 2013-01-23

    Verified the fix works as expected with TiSDK 3.0.2.v20130122151702 Device tested: Nexus One 2.2.2 Nexus Tab 10" 4.2 Closing.

JSON Source