WatchUi.requestUpdate doesn't do anything in datafield (SettingsView)

I'm implementing a custom picker in the settings view of a datafield. It seems that even though the documentation of requestUpdate doesn't say anything about datafields the onUpdate is called once a second (there it does say) no matter if I call requestUpdate or not.

Question 1: is there any trick that can be done to be able to refresh the settings view immediately after a key press? It lags so much, which is annoying by itself, but it also makes inputting text very slow...

Question 2: should I open a request to add something like "requestUpdate doesn't do anything if called in datafield"?

  • That’s interesting, because when it tried to implement a settings view for a datafield ages ago, I found that onUpdate() was not called regularly, but only after user input, which made it impossible to use the settings view for anything other than…settings. (I wanted to abuse the settings view for a “live” secondary data field app view, such as a lap list or a 2nd map page, but it seemed to me that Garmin either doesn’t care about that type of use case or they explicitly wanted to prevent it.

  • Interesting, then a) I'll try some other devices in the simulator, b) I'll try it in 2 of my devices (fenix6, fr965) to see if it behaves similar to the sim, but maybe then I shouldn't delete the seemingly unnecessary calls to requestUpdate?

  • I tried this in a few devices in the 6.4.2 simulator and all behaved the same way:

    1. views that extend Menu2 only call onUpdate when the user clicks.

    2. views that extend View call onUpdate every second (on the same ms) even when you don't call requestUpdate, and even if you call requestUpdate it only calls onUpdate at the same time in the next second as you haven't call requestUpdate.

    However I noticed 1 exception: the view that extends View does call onUpdate immediately when the view is switched into it. In other words when we pushView it so it's on the top of the view stack, or when we popView the view above it. So I came up with the following workaround that seems to work in the simulator:

    class ForceUpdateView extends WatchUi.View {
        function onShow() as Void {
            log("ForceUpdateView.onShow");
            WatchUi.popView(SLIDE_IMMEDIATE);
        }
        function onUpdate(dc as Graphics.Dc) as Void {
            // this is needed to prevent flickering
        }
    }
    
    function forceUpdate() as Void {
        WatchUi.pushView(new ForceUpdateView(), null, SLIDE_IMMEDIATE);
    }

    And instead of WatchUi.requestUpdate I call forceUpdate();

  • Interesting, thanks! However, last time I checked (a long time ago), MapView wasn’t updated every second when launched via on-device settings. (I was toying with the idea of implementing a data field which has a 2nd map as an “alternate screen”, since some people have asked for a 2nd map page in the forums.)

    I think I launched the MapView via a Menu (same with the other “alternate views” I tried.) I wonder if the type of the top-level view is what determines this behavior.

  • I don't think the top level view (whatever that means? Do you mean getInitialView() or getSettingsView()?) decides, because if that was the case then onUpdate would be called on the settings and on the custom view similarily. Maybe the app type has something to do with it (i.e that explains why the custom view's onUpdate is called every second) but then why isn't it also calling the menu's onUpdate.

  • I meant the view returned by getSettingsView(). I was referring to a data field (just like you), as mentioned above. I just don’t get why I saw different behavior than you, unless it’s changed since then.

  • getSettingsView returns: MySettingsMenu extends Rez.Menus.SettingsMainMenu that is menu2 in xml.
  • So my previously posted solution doesn't really work (except the simulator). There are 2 problems with it:

    1. on real device it's flickering (even with the empty onUpdate)

    2. on real device onUpdate is not called at all, so the screen isn't updated (it doesn't matter if I call requestUpdate or the above trick)

  • on real device onUpdate is not called at all

    Yep this is what I found previously, which is why I gave up the dream of creating a CIQ data field with a secondary view with live data that can accept input Sob

    (The best I can do is create a CIQ data field that allows the user to switch pages via a lame ”gesture” such as press DOWN, UP quickly.)

  • the problem with that (if it even works) is the user experience on touch screen devices will be horrible. On Watches it's so-so, but in edges, where the prev/next button (that on the watch are up/down) are mapped in the BehaviourDelegate to left and right swipes...