takataka430’s blog

.NET系を中心に勉強したことのまとめを書きます

【Xamarin.Forms】ProgressBarを使い、繰り返し処理の進捗を表示してみた

モバイルアプリで何か処理をするために数十秒くらいの時間がかかる場合、ユーザーからするといつ終わるのか目安みたいなものが欲しいですよね?このような場合にどうすればいいのか調べていたところ、Xamarin.Formsには「ProgressBar」というものがあることを知りました。

ProgressBarとは

進捗を表すコントローラのことです。このクラスはProgressというプロパティを持っており、ここに値(最大値は1)を入れることによって進捗バーの色の領域が変わります。例えば、Progressプロパティが0.4の場合は以下の画像のようになります。

f:id:takataka430:20190221203806p:plain:w200

画像の通り、左から40%が色付きの領域になっていることがわかります。
詳しくは以下のドキュメントをご覧ください。

docs.microsoft.com

繰り返し処理の進捗をProgressBarで表示してみた

それでは本題です。今回はコレクションから要素を一つずつ取り出し、何らかの処理を繰り返す場合を考えてみました。コードは以下の通りです。

画面

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:local="clr-namespace:XF_ProgressBar" 
             x:Class="XF_ProgressBar.MainPage">
    <StackLayout VerticalOptions="Center">
        <Button x:Name="button"
                Text="Button"
                Clicked="Handle_Clicked"/>
        <ProgressBar x:Name="progress"/>
        <Label x:Name="label"
               HorizontalOptions="Center"/>
    </StackLayout>
</ContentPage>

  
コードビハインド

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace XF_ProgressBar
{
    public partial class MainPage : ContentPage
    {
        //1が1000個あるコレクション
        IEnumerable<int> numbers = Enumerable.Repeat(1, 1000);

        public MainPage()
        {
            InitializeComponent();
        }

        async void Handle_Clicked(object sender, EventArgs e)
        {
            label.Text = "";
            int sum = 0;
            var amount = numbers.Count();    //コレクションの要素数
            var operated = 0;                //処理済みの回数を初期化
            foreach(var number in numbers) 
            {
                sum = sum + number;
                operated += 1;
                progress.Progress = (double)operated / amount;  //ここで進捗率を計算
                await Task.Delay(1);                            //一瞬で終わってしまうので見やすいように1ミリ秒待つようにしています
                label.Text = sum.ToString();
            }
        }
    }
}

1が1000個入っているコレクションから値を一つずつ取り出し加算するという処理を行い、ProgressBarで進捗を表しています。また、加算の結果は随時ラベルで表示するようにしています。
実行すると以下のようになります。

f:id:takataka430:20190221203709g:plain:w200

いい感じですね!
今回行った加算処理を他の処理に置き換えれば色々な進捗の表示に使えるのではないかと思います。