Is onShow() available to Menu2?

This may be a dumb question so I apologize in advance.

I see in the API documentation it says that onShow() is inherited from the View class. In the following code that is in the documentation, you create a menu and then push the view onto the screen.

So my question is where would onShow() need to be implemented to be accessible? 

   function onMenu() {
        var menu = new WatchUi.Menu2({:title=>"My Menu2"});
        var delegate;
        menu.addItem(
            new MenuItem(
                "Item 1 Label",
                "Item 1 subLabel",
                "itemOneId",
                {}
            )
        );
        menu.addItem(
            new MenuItem(
                "Item 2 Label",
                "Item 2 subLabel",
                "itemTwoId",
                {}
            )
        );
        delegate = new MyMenu2Delegate(); // a WatchUi.Menu2InputDelegate
        WatchUi.pushView(menu, delegate, WatchUi.SLIDE_IMMEDIATE);
        return true;


Thanks
  • You really only have access to the delegate and not the view for the menu itself.

    What would you want to use onShow() for?

  • Now that I think of it I'm not sure it would have worked the way I was hoping.

    Basically trying to find the most logical way to update menu items.

    In my case, I have settings that I show with a sublabel, example below. The problem is sometimes these can be nested, and I was wanting to update all menu items when the Menu is brought to the top of the view stack.

    Label = Alarm (Setting)

    SubLabel  = 8:00AM (Setting Selection)

  • What you can try is pass the menu to the delegate, and in the delegate add/remove menu entries

        delegate = new MyMenu2Delegate(menu); // a WatchUi.Menu2InputDelegate
        WatchUi.pushView(menu, delegate, WatchUi.SLIDE_IMMEDIATE);

  • Just like any other method, if you want to override it you need to extend and implement...

    using Toybox.Application;
    using Toybox.WatchUi;
    
    class MyMenu2 extends WatchUi.Menu2
    {
        function initialize(options) {
            Menu2.initialize(options);
        }
        
        function onLayout(dc) {
            System.println("MyMenu2.onLayout");
        }
        
        function onShow() {
            System.println("MyMenu2.onShow");
        }
    
        function onHide() {
            System.println("MyMenu2.onHide");
        }
    }
    
    class MyMenu2InputDelegate extends WatchUi.Menu2InputDelegate
    {
    	function initialize() {
    		Menu2InputDelegate.initialize();
    	}
    	
    	function onSelect(item) {
    		WatchUi.popView(WatchUi.SLIDE_IMMEDIATE);
    		return true;
    	}
    }
    
    class Menu2TestView extends WatchUi.View {
    
        function initialize() {
            View.initialize();
        }
    }
    
    class Menu2TestDelegate extends WatchUi.BehaviorDelegate {
    
        function initialize() {
            BehaviorDelegate.initialize();
        }
    
    	function onMenu() {
    		var menu2 = new MyMenu2({:title=>"My Menu2"});
    		menu2.addItem(
    		    new WatchUi.MenuItem(
    		        "Item 1 Label",
    		        "Item 1 subLabel",
    		        "itemOneId",
    		        {}));
    		
    		menu2.addItem(
    		    new WatchUi.MenuItem(
    		        "Item 2 Label",
    		        "Item 2 subLabel",
    		        "itemTwoId",
    		        {}
    		    ));
    		    
    		WatchUi.pushView(menu2, new MyMenu2InputDelegate(), WatchUi.SLIDE_UP);
    	}
    }
    
    class Menu2TestApp extends Application.AppBase {
    
        function initialize() {
            AppBase.initialize();
        }
    
        function getInitialView() {
            return [ new Menu2TestView(), new Menu2TestDelegate() ];
        }
    }

    If you inherit from WatchUi.Menu2, you can put all of the code necessary to build up your menu inside the menu implementation instead of having it in the delegate. This isn't typically a big deal, but it is sometimes nice.

    You can also add/remove menu items from within any of those functions, provided that the menu is not empty when you return.

  • I was trying to do something similar and found this thread.  I tried to implement the Travis's  MyMenu2 class in a test I was doing for nested menus.  The class would build a menu fine and run, but I never could use it to refresh the menu sublabel items once the underlying variable was updated using a picker and the picker view was popped.

    In the end, I worked out a solution to write all of my menus in a menus module.  Then I call the needed menus.buildmenu() function for the menu I want in the menu delegate.  Now when I pop the picker view, I also pop the menu and call the buildmenu function again.  Instant data refresh with the new data saved from the picker, and I still only have one code to maintain for the menu and get the flexibility to call it from multiple locations.  It proved easier than trying to pass the menu to the delegate or getting the class to work.

  • I'm almost certain that we have test apps that add and modify menu items when Menu2.onShow() is called.