Development (Advanced)

Step 1: Adding the assets

  1. Download and unpack the extended assets file.

    The basic assets pack consists of one folder...

    ... which contains one additional image:

    • charging image file (res/charging.png)

  2. Select the unpacked folder, that is res, and copy them with context menu or press Control + C. Next, make a left mouse click on the project name WatchFace in Solution Explorer and press Control + V to paste copied folders directly to the WatchFace project.

  1. Confirm the following pop-up to replace the content of the res folder of the project.

  1. Make sure that there are required files copied into the project folders.


Step 2: Updating the view

  1. Go to Solution Explorer window and open the TextWatchApplication.xaml file.

  1. Add a Label element responsible for displaying a percentage value of the battery level and an Image element responsible for displaying a charging indicator.

    <?xml version="1.0" encoding="utf-8" ?>
        <Application xmlns="http://xamarin.com/schemas/2014/forms"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     x:Class="WatchFace.TextWatchApplication">
            <Application.MainPage>
                <ContentPage>
                    <AbsoluteLayout>
                        <Image AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                               Source="background.png" />
    
                        <Image AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                               Source="satellite.png"
                               Rotation="{Binding SecondsRotation}" />
    
                        <Label AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                               HorizontalTextAlignment="Center"
                               VerticalTextAlignment="Center"
                               FontAttributes="Bold"
                               FontSize="26"
                               TextColor="#FFFFFF"
                               Text="{Binding Time, StringFormat='{}{0:HH:mm}'}" />
    
                        <Label AbsoluteLayout.LayoutBounds="150, 269, 60, 25"
                               HorizontalTextAlignment="Center"
                               VerticalTextAlignment="Center"
                               FontSize="6"
                               TextColor="#C0D5F4"
                               Text="50%" />
    
                        <Image AbsoluteLayout.LayoutBounds="142, 275, 10, 13"
                               Source="charging.png"
                               IsVisible="True" />
                    </AbsoluteLayout>
                </ContentPage>
            </Application.MainPage>
    </Application> 
    

At this point, you should have a watchface, which displays not only time and seconds' indicator, but also charging icon and fixed battery level percent. On the next steps, we are going to read actual data from Tizen Battery API.


Step 3: Updating the view model

  1. Go to Solution Explorer window and open the ClockViewModel.cs file.

  1. Add two properties responsible for storing information about battery percentage level (BatteryPercent) and charging state (IsCharging).

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace WatchFace
    {
        public class ClockViewModel : INotifyPropertyChanged
        {
            DateTime _time;
    
            public DateTime Time
            {
                get => _time;
                set
                {
                    if (_time == value) return;
                    _time = value;
                    OnPropertyChanged();
    
                    SecondsRotation = _time.Second * 6;
                    OnPropertyChanged(nameof(SecondsRotation));
                }
            }
    
            public int SecondsRotation { get; private set; }
            public bool IsCharging { get; private set; }
            public int BatteryPercent { get; private set; }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    
  2. Add a using statement for Tizen.System to get access to the Tizen Battery API.

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Tizen.System;
    
  3. Create a class constructor and set initial values to created properties.

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using System.Tizen;
    
    namespace WatchFace
    {
        public class ClockViewModel : INotifyPropertyChanged
        {
            DateTime _time;
    
            public DateTime Time
            {
                get => _time;
                set
                {
                    if (_time == value) return;
                    _time = value;
                    OnPropertyChanged();
    
                    SecondsRotation = _time.Second * 6;
                    OnPropertyChanged(nameof(SecondsRotation));
                }
            }
    
            public int SecondsRotation { get; private set; }
            public bool IsCharging { get; private set; }
            public int BatteryPercent { get; private set; }
    
            public ClockViewModel()
            {
                IsCharging = Battery.IsCharging;
                BatteryPercent = Battery.Percent;
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    
  4. Extend the class constructor by defining handlers of ChargingStateChanged and PercentChanged events.

    public ClockViewModel()
    {
        IsCharging = Battery.IsCharging;
        BatteryPercent = Battery.Percent;
    
        Battery.ChargingStateChanged += OnChargingStateChanged;
        Battery.PercentChanged += OnPercentChanged;
    }
    
  5. Implement defined event handlers.

    public ClockViewModel()
    {
        IsCharging = Battery.IsCharging;
        BatteryPercent = Battery.Percent;
    
        Battery.ChargingStateChanged += OnChargingStateChanged;
        Battery.PercentChanged += OnPercentChanged;
    }
    
    private void OnPercentChanged(object sender, BatteryPercentChangedEventArgs e)
    {
        BatteryPercent = e.Percent;
        OnPropertyChanged(nameof(BatteryPercent));
    }
    
    private void OnChargingStateChanged(object sender, BatteryChargingStateChangedEventArgs e)
    {
        IsCharging = e.IsCharging;
        OnPropertyChanged(nameof(IsCharging));
    }
    

So we already have all data needed to display battery properties on the watch face.

All that is left is to bind them to the user interface.


Step 4: Creating bindings to the view model

  1. Go to Solution Explorer window and open the TextWatchApplication.xaml file.

  1. Create bindings to previously created view model properties.

    <?xml version="1.0" encoding="utf-8" ?>
    <Application xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="WatchFace.TextWatchApplication">
        <Application.MainPage>
            <ContentPage>
                <AbsoluteLayout>
                    <Image AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                           Source="background.png" />
    
                    <Image AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                           Source="satellite.png"
                           Rotation="{Binding SecondsRotation}" />
    
                    <Label AbsoluteLayout.LayoutBounds="0, 0, 360, 360"
                           HorizontalTextAlignment="Center"
                           VerticalTextAlignment="Center"
                           FontAttributes="Bold"
                           FontSize="26"
                           TextColor="#FFFFFF"
                           Text="{Binding Time, StringFormat='{}{0:HH:mm}'}" />
    
                    <Label AbsoluteLayout.LayoutBounds="150, 269, 60, 25"
                           HorizontalTextAlignment="Center"
                           VerticalTextAlignment="Center"
                           FontSize="6"
                           TextColor="#C0D5F4"
                           Text="{Binding BatteryPercent, StringFormat='{0}%'}" />
    
                    <Image AbsoluteLayout.LayoutBounds="142, 275, 10, 13"
                           Source="charging.png"
                           IsVisible="{Binding IsCharging}" />
                </AbsoluteLayout>
            </ContentPage>
        </Application.MainPage>
    </Application>
    

Right now the application can be run on the target device and set as the device watch face. As you can see, the charging indicator is displayed only when the device is plugged in to the charger. Additionally, the current value of the battery level is displayed on the screen.

To build and run this application on the device, follow the steps below:

  • Press Ctrl+Shift+B keys to build the project.

  • Press Ctrl+F5 keys to start installing the application.

You're done!

Congratulations! You have successfully achieved the goal of this Code Lab activity. Now, you can develop your own Digital Watch Face by yourself! But, if you're having trouble, you may check out the link below.

Watch Face Complete Code1.71MB