How to make dynamic DataFieldAlert

So I have this datafield, and when the HR (not the buil-in, but one I get via ANT) gets high I display an alert. This works, but this is a one-time static alert: "HR High: 180".

I'd like to improve that by:

a) update the HR

b) close the alert when the HR gets again below the threshold

My problem is that it seems that in DataFieldAlert only onUpdate() is being called but compute() isn't.

BTW what I tried to do is:

public function compute(info as Activity.Info) as Void {
    mParentView.compute(info);
}
(This is because the parentView (the usual view of the datafield) already has all the code that takes care of all the calculations and I don't want to copy that)
  • Is onUpdate() in DataFieldAlert only called once (when the alert is initially displayed) or is it called continuously (e.g. once per second)?

    If it's called continuously, you could give the DataFieldAlert class access to a function in the data field view which provides the information it needs.

    If it's only called once, then you're probably out of luck unless you trigger the alert multiple times for a period of a few seconds (although that might not be the best user experience).

    Not directly related, but I noticed that the on-device settings view doesn't respond to WatchUi.requestUpdate(), which means that it can't be used for dynamic data either. (Which sucks, because otherwise it could've been used for so many other things besides settings, but I guess it's by design.)

  • Yes, onUpdate is called every second. Probably I'll do what you recommended, but I didn't want to do it, I thought maybe there's a better way. This is too much hacky

  • onUpdate is called every second if the DF is visible.  If the DF is on the second data screen and that's what a user is looking at, onUpdate is called.  If the user switches to the first data screen, onUpdate is not called every second.  compute is always called every second,  If you use the same DF twice on the same screen, it gets interesting.  onLayout and onUpdate get called for each DF every second, while compute is only called once per second.

    That said, I have DFs that I wrote back in CIQ 1 that will display a message under certain conditions, and it's  handled in onUpdate.  in onUpdate, I have a flag if a message needs to be displayed, and if that's not true, I display the normal data.  If there is a message to display, I display that instead.  I have a counter that I decrease each time the message is displayed, so it handles displaying a message for "X" seconds when the DF is visible  Some messages don't time out, but are removed under a condition such as recording starts or a DF layout works with the data field.  

  • Does it mean that if user put 2 the same DF, both are based on the same, single instance/object of DF? 

  • onUpdate is called every second if the DF is visible. 

    This thread is about data field *alerts*

  • Does it mean that if user put 2 the same DF, both are based on the same, single instance/object of DF? 

    Yep, iirc. If you want to run two independent instances of the same data field, you have to create a clone in the store.

  • OK, if this thread was already captured, then I'll also ask another thing about this. I noticed this in the simulator, and didn't care too much, but maybe someone has a good idea about this:

    At the beginning I tried to optimize my datafield in such a way that I cache some measurements and basic calculations (like biggest font that fits to the available area) in onLayout, and do the minimum in onUpdate. But this nice theory broke down in the simulator when there's a layout with more than 1 field on it. So I moved this code to the beginning of onUpdate. Still trying to cache if possible (so in real device with only 1 instance on the screen it should be almost as good as it would be if I cached things in onLaypout) But maybe someone has some better idea. I don't know, maybe a trick how to identify the different data field locations on the screen. For example can dc be used as a key in a map and store the cached values in that map (I never tried this, just an idea):

    class Cache {
      var foo,bar...
    }
    var cache as Dictionary;
    onLayout(dc) {
      if (cache[dc] == null) {
        var c = new Cache();
        // calculate and store the cached values in c based on dc
        cache[dc] = c;
      }
    }
    onUpdate(dc) {
      var c = cache[dc];
    }

    Or any better idea?

  • I've made some test but in WF and it's possible. But in DF it rather won't run because there are "two dces".

  • Almost a year later. I calculate my layouts in layout then cache them.

    For each layout I produce a key. For rectangular that can just be concatenation of height and width.  You then have a dictionary of layouts acting as a cache. Each time on layout is called, you check the cache to see if you’ve already calculated that key. If so you just return.  Then in onUpdate you pull the calculated layout values out of your cache using your key..  Works whether your field is in one place or multiple.