How to Use Selectable Objects in Garmin ConnectIQ Apps

This post describes how to use Selectable objects in Garmin ConnectIQ apps with a practical example and code snippets.

First what is Selectable? as per Garmin SDK documentation:

Selectable is the class representation of an on-screen selectable object with defined states depending on selection mode.

In other words it’s the UI element to handle user input on watches with touch screens, it becomes inevitable to use in case there are no physical buttons (other than the main select button) - Vivoactive watches for example. It’s available since SDK version 2.1.0.

An example for using Selectable was in one of the apps I worked on; Miqat is a Multi-timer app for workouts, it provides different modes for different training needs, one of which is AMRAP (As many rounds as possible). In this mode users could increment or decrement the number of rounds their achieved so far.

Miqat AMRAP use-case

When user taps anywhere in the green area the rounds are incremented and when tapping on the red area they are decremented.

For Garmin watches with physical UP and DOWN buttons it’s easy to capture those events with onKey function that’s triggered on key presses, but for watches without physical buttons we need to respond to user touch events, this can be achieved using Selectable objects.

Let’s start off by defining a class which inherits from Selectable.

using Toybox.WatchUi;

module Selectables {
  class Up extends WatchUi.Selectable {
    function initialize(options) {
      Selectable.initialize(options);
    }
  }
}

In order for this Up selectable to be available for users, it needs to be drawn on a view, for that we can use the Custom Drawables feature of Layouts where we specify the class of the drawable and define it’s position on the screen

<drawable class="Selectables.Up">
  <param name="locX">0</param>
  <param name="locY">0</param>
  <param name="width">300</param>
  <param name="height">150</param>
</drawable>

onSelectable method is called whenever the state of a selectable is changed, so in the BehaviourDelegate of this view we can handle Selectable state changes

class SelectableExampleDelegate extends WatchUi.BehaviorDelegate {
  function initialize() {
    BehaviorDelegate.initialize();
  }

  function onSelectable(event) {
    var instance = event.getInstance();

    if (instance.getState() == :stateSelected) {
      handleSelectedState(instance);
    }
    return true;
  }

  function handleSelectedState(instance) {
    if(instance instanceof Selectables.Up) {
      System.println("up");
    } else if (instance instanceof Selectables.Down) {
      System.println("down");
    }
  }
}

That’s it, now you can define what do when each Selectable is selected; i.e. tapped according to your business logic.

If you want to check the complete code for this example, feel free to refer to: SelectableExample.

comments

comments powered by Disqus