Xamarinでタイマーを実装する方法

XamarinでiOSアプリにタイマーを実装する方法を紹介します。

この記事では、System.Timers.Timerは使わずに、Task.Delay()を使用する方法を記載しています。

System.Timers.Timerが動作しなかった人向けの代替策です。

0. この記事で実装したいイメージ

以下のツイートのように、1秒ずつカウントダウンしていきます。

「分:秒」で表示させています。

1. タイマーのカウントダウンロジック

System.Threading.Tasks.Task.Delay(1000)で、1秒待つというロジックになります。

これを while でループさせています。

while ループを抜ける条件としては、「timeLimitSecが0より大きい」としています。


private int timeLimitSec = 10;

async void StartTimer()
{
    while(true && timeLimitSec > 0)
    {
        await System.Threading.Tasks.Task.Delay(1000);
        timeLimitSec = timeLimitSec - 1;
    }
}

2. 秒から「分:秒」の表示に変換する

秒(int型)から「分:秒」の表示に変換するには、TimeSpanを使用します。

以下のコードでは、TimerCountというラベルのテキストにセットしています。

TimerCount.Text = new TimeSpan(0, 0, timeLimitSec).ToString(@"mm\:ss");

TimerSpanの第3引数に「秒」をセットし、ToString()で文字列に変換します。

ちなみに、macでバックスラッシュを入力するには、「 option + ¥」です。

3. View部分(xaml)

タイマー表示用として、TimerCountという名前のラベルを設置します。


<Label x:Name="TimerCount"></Label>

4. 実行例

以下のように表示されれば成功です。

5. Task.Delay の問題点

タイマーカウントダウンのロジックは以下の通り Task.Delayを使用しています。

while(true && timeLimitSec > 0)
{
    await System.Threading.Tasks.Task.Delay(1000);
    timeLimitSec = timeLimitSec - 1;
}

そのため、このタイマーを一時的にストップする場合は、最大で1秒の遅延が発生します。

Task.Delay(1000)の部分で一秒待つためです。

6. タイマーの一時停止機能を実装する方法

タイマーの一時停止機能を実装してみましょう。

まず、View(xaml)にスタートとストップのボタンを設置します。

<Button x:Name="TimerStart" Clicked="TimerStart_Clicked" Text="TimerStart"></Button>
<Button x:Name="TimerStop" Clicked="TimerStop_Clicked" Text="TimerStop"></Button>

タイマーカウントダウンロジックを一部修正します。

ループ条件にtimerEnableというbool変数を使用します。


private bool timerEnable = false;

async void StartTimer()
{
    while(timerEnable && timeLimitSec > 0)
    {
        await System.Threading.Tasks.Task.Delay(1000);
        timeLimitSec = timeLimitSec - 1;
        TimerCount.Text = new TimeSpan(0, 0, timeLimitSec).ToString(@"mm\:ss");

    }
}

TimerStart_Clickedイベントトリガーで、タイマーを開始します。

void TimerStart_Clicked(System.Object sender, System.EventArgs e)
{

timerEnable = true;
StartTimer();

}

TimerStop_Clickedイベントトリガーで、タイマーを停止します。

void TimerStop_Clicked(System.Object sender, System.EventArgs e)
{
    timerEnable = false;
}

7. この記事で紹介したソースコード全文

  • TaskTimer.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="todotimer.TaskTimer">
    <ContentPage.Content>

        <StackLayout>

            <Button x:Name="TimerStart" Clicked="TimerStart_Clicked" Text="TimerStart"></Button>
            <Button x:Name="TimerStop" Clicked="TimerStop_Clicked" Text="TimerStop"></Button>

            <Label x:Name="TaskName"></Label>
            <Label x:Name="TimerCount"></Label>
            <Label x:Name="DeviceCount"></Label>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
  • TaskTimer.xaml.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace todotimer
{
    public partial class TaskTimer : ContentPage
    {

        private int count = 0;
        private int timeLimitSec = 10;
        private bool timerEnable = false;

        public TaskTimer(string TodoName)
        {
            InitializeComponent();
            TaskName.Text = TodoName;
            TimerCount.Text = new TimeSpan(0, 0, timeLimitSec).ToString(@"mm\:ss");

        }

        async void StartTimer()
        {
            while(timerEnable && timeLimitSec > 0)
            {
                await System.Threading.Tasks.Task.Delay(1000);
                timeLimitSec = timeLimitSec - 1;
                TimerCount.Text = new TimeSpan(0, 0, timeLimitSec).ToString(@"mm\:ss");

            }
        }

        void TimerStart_Clicked(System.Object sender, System.EventArgs e)
        {
            timerEnable = true;
            StartTimer();
        }

        void TimerStop_Clicked(System.Object sender, System.EventArgs e)
        {
            timerEnable = false;
        }
    }
}

コメント

タイトルとURLをコピーしました