Using CircularUI

Xamarin.Forms abstracts different User Interface(UI) components across various platforms to a single interface by grouping similar UI components. However, some UI components are hard to categorize, because they are closely tied to the device hardware features. Indeed, most Galaxy Watches in the market have a round-shaped screen while most smartphones and some watches, which the Xamarin.Forms targets, have a square-shaped screen. Designers and developers want to create more aesthetic and effective UI controls that fit well in the hardware features of Samsung Galaxy Watch. Therefore, the Tizen.Wearable.CircularUI.Forms API provides a variety of UI controls to help developers easily create UIs for round-shaped wearables.

Figure 1. UI controls of CircularUI

Using the CircularUI library

For our MySteps app, we'll now add a round-shaped progress bar that lies around the edges of the screen. Our goal is to visually show how many steps the user has walked compared to 6000 steps, which an average person walks a day.

Circle-shaped UI controls such as CircleProgressBarSurfaceItem is placed on the CircleSurfaceView object, which acts as a container that shows CircleProgressBarSurfaceItem objects and other circle-shaped UI controls. The following image shows a simplified UML diagram of the relevant classes. Additionally, it visualizes how we intent to add the CircleProgressBarSurfaceItem object to MySteps.

Figure 2. CircleSurfaceView and CircleProgressBarSurfaceItem structure

Since we also have to add a Label object in the center of the screen to show the number of steps of the user, we would have to add the label on top of the CircleSurfaceView object. This requires using a layout that overlays its children on top of each other such as an AbsoluteLayout. Using an AbsoluteLayout, you can place its children on the layout by specifying the absolute or proportional position. For more information, you can see the AbsoluteLayout guide.

Change to AbsoluteLayout

We will first replace the current StackLayout to an AbsoluteLayout and place the Label object in the center of the screen. Take the following steps:

In the StepCountPage.xaml,

  1. Replace StackLayout to AbsoluteLayout.

  2. In the Label element, erase the VerticalOptions and HorizontalOptions attributes.

  3. In the Label element, add AbsoluteLayout.LayoutFlags to All. Then, add AbsoluteLayout.LayoutBounds attribute and set its value to "0.5, 0.5, 0.5, 0.25".

    Setting AbsoluteLayout.LayoutFlags to All specifies that all values in AbsoluteLayout.LayoutBounds are proportional. The comma-separated four values of the AbsoluteLayout.LayoutBounds specifies the X anchor, Y anchor, Width, and Height of the view, in that order.

    When proportional values are used, the width and height values of an element is proportional to its parent. In our case, the Label has a width half of its parent and a height 1/4 of its parent.

    The anchor point is a representative point of the element. The default anchor point is at the top-left edge of the element. When proportional values are used, the anchor point's position is proportional to its element's width(for x anchor) and height(for y anchor), and is also proportional to its parent view's width(for x anchor) and height(for y anchor). It is a unique anchor model that makes positioning elements easier. For more information you can see the AbsoluteLayout guide.

  4. In the Label element, add HorizontalTextAlignment and VerticalTextAlignment attributes and set their value to "Center".

    This will place the text in the center within the Label object both horizontally and vertically.

The following shows the finished code:

...
<AbsoluteLayout>
    <Label
      AbsoluteLayout.LayoutBounds="0.5, 0.5, 0.5, 0.25"
      AbsoluteLayout.LayoutFlags="All"
      Text="0 Steps"
      FontSize="Large"
      HorizontalTextAlignment="Center"
      VerticalTextAlignment="Center"/>
</AbsoluteLayout>
...

Add CircleProgressBarSurfaceItem

First, ensure that FormsCircularUI.Init() is called after (Xamarin's) Forms.Init() to initialize Tizen Wearable CircularUI in the Main function. In this tutorial, it's located in the MySteps.cs as follows:

...
using Tizen.Wearable.CircularUI.Forms;
...
static void Main(string[] args)
{
    var app = new Program();
    Forms.Init(app);
    FormsCircularUI.Init();
    app.Run(args);
}

Now, return to StepCountPage.xaml and take the following steps:

  1. Add the CircularUI namespace in XAML:

    <ContentPage
      x:Class="MySteps.StepCountPage"
      xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      xmlns:w="clr-namespace:Tizen.Wearable.CircularUI.Forms;assembly=Tizen.Wearable.CircularUI.Forms"
      NavigationPage.HasNavigationBar="False">
      ...
    

    You need to define a XML namespace(xmlns) declaration with a prefix to use the class types from the Tizen.Wearable.CircularUI.Forms namespace. This step requires you to fill out three things: the xmlns prefix, the clr-namespace name, and the assembly name. The xmlns prefix can be chosen arbitrary, for example, we've used w for the prefix to represent the word wearable. The clr-namespace name specifies the Common Language Runtime(CLR) namespace that exposes the class types to be used in XAML, in our case it is the Tizen.Wearable.CircularUI.Forms namespace. The assembly name is optional if the CLR-namespace is within the same assembly as the application code. In our example, however, MySteps references the types from another assembly named Tizen.Wearable.CircularUI.Forms. If you want to know more about declaring namespaces in XAML, see XAML namespaces.

  2. Add the following XAML code above the Label element(between the <AbsoluteLayout> and the <Label> tags):

    <w:CircleSurfaceView
      AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
      AbsoluteLayout.LayoutFlags="All">
      <w:CircleSurfaceView.CircleSurfaceItems>
        <w:CircleProgressBarSurfaceItem
                      x:Name="ProgressBar"
                      BackgroundColor="LightBlue"
                      BackgroundLineWidth="10"
                      BackgroundRadius="175"
                      BarColor="Blue"
                      BarLineWidth="10"
                      BarRadius="175"
                      IsVisible="True"
                      Value="0" />
      </w:CircleSurfaceView.CircleSurfaceItems>
    </w:CircleSurfaceView>
    

    CircleProgressBarSurfaceItem has a background area and a bar area, the background area is a round-shaped ring and the bar area fills up the ring depending on the Value attribute. The following image shows the meaning of the BackgroundRadius/BarRadius and BackgroundLineWidth/BarLineWidth. Note that the Galaxy Watch emulator has a 360*360 screen size, hence the values of the BackgroundRadius/BarRadius and BackgroundLineWidth/BarLineWidth attributes are chosen so that the CircleProgressBarSurfaceItem is placed at the edges of the screen.

    Figure 3. Radius and LineWidth meaning of CircleProgressBarSurfaceItem
  3. Fix the UpdateData() method that so that the progress bar changes according to the number of steps.

    void UpdateData(object s, EventArgs e)
    {
        ProgressBar.Value = (double)pedometer.StepCount / 6000;
        label.Text = pedometer.StepCount.ToString() + " Steps";
    }    
    

Run MySteps

We've added a progress bar in XAML using the Tizen.Wearable.CircularUI.Forms API. We then update the Value property of CircleProgressBarSurfaceItem along with the Text property of Label whenever the pedometer.DataUpdated event occurs. The following animation shows the execution of MySteps with a circle progress bar.

Figure 4. Circular progress bar

Next Steps

Congratulations on completing the tutorial. Now you know the basics of Samsung Galaxy Watch application to develop more complex applications.