Best practice to render WatchUi.View

Former Member
Former Member

How do you render your WatchUi.View, do you use layouts or only Graphics.Dc?

I don't know which way is better, and I suppose you can't combine these two approaches.

For example I would like to draw a graph, so I can't use layout I should use only Graphics.Dc methods.

Maybe I am wrong, but as I understand with layout you have to set all coordinates for each element which is much harder,

than calculate them in runtime and draw with Graphics.Dc.

  • This is a bit of personal choice, as you can do layouts, direct dc or a combo.

    You can have a different layout per target, so the calculations needed at runtime are minimal, and after the View.onUpdate() do direct dc to add extra things over it, or just always used direct dc calls.

    For me, I just always use direct dc calls.  The thing here, is you want to avoid figuring things out each time onUpdate() is called.  I'll do that in onLayout, and set the x/y/font used at that time, where you can also us things like the font height for one thing to set the x/y for something else.

  • I've done both approaches, when using the layout system it's easier to keep the code clean, if memory is an issue then you have no choice and have to go for the dc.draw approach

  • I've done a hybrid approach for full-screen data fields (2 to 6 fields). I built my own memory-efficient layout system which gets rendered using Dc.Draw(). The big advantage for me is that I could load layouts from JSON storage, which allows me to implement multiple layouts and optimize for multiple devices without the memory overhead which would've been incurred by hard-coded (or even dynamically calculated) Dc.draw() calls.

    I store the layout info itself in byte/bit-packed arrays of Numbers -- I managed to fit all the layout info (coordinates/alignment/font) for each "element" (e.g. field header or value) into 2 Numbers (32-bit integers). My onUpdate() code iterates through the array and draws text with the layout info specified by the array members. e.g. A layout that has 6 fields (6 headers and 6 values) can be represented by 24 numbers (2 x 12) in this system, or a little over 96 bytes of RAM (4 x 24 + whatever the overhead is for an Array in Monkey C). 

    As JSON doesn't support bit shifts and logical OR (or even comments), and it would be unmaintainable/unreadable to hardcode the results of all the bit/byte-packing, I store the original data in a separate format that does support bit shifts and logical OR, and as a pre-build step, I compile the data to JSON.

    I admit it's pretty elaborate, but I managed to save a lot of memory this way, while still having the flexibility of layouts.

  • Former Member
    0 Former Member in reply to peterdedecker

    when I have to start think about memory?

    I mean, how should understand it, that app is already big for a smartwatch and I need optimization?

  • Garmin apps are very memory-limited, especially data fields (16 KB for FR235, 32 KB for Vivoactive 3, to pick a couple of popular watches). If your app goes over the memory limit, it automatically crashes. These limits are miniscule compared to most modern platforms (and even computers that are decades old).

    If you develop data fields, you'll find that you can run out of memory very quickly when you start adding features or fancy graphics. It's less of an issue for "device apps" and watchfaces, which have a bit more available memory.