Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.Formsでダイアログボックス(とBusyインジケーター)を表示するには?

2014年7月2日

ダイアログ(=iOSのUIAlertView/AndroidのAlertDialog)や、処理実行中を示すBusyインジケーターを、Xamarin.Formsで表示する方法を解説する。これらは共通のAPIを使って実装できる。

奥山 裕紳(@amay077
  • このエントリーをはてなブックマークに追加

 ダイアログボックスの表示は、Androidでは主にAlertDialog、iOSではUIAlertViewを使用するが、Xamarin.Formsは、これらを使うための共通なAPIを提供する。このAPIの使用方法について解説する。

1. Xamarin.Formsプロジェクトを作成する

 アラートダイアログを表示するためのプロジェクトを作成する。

 Xamarin Studioのメニューバーの[ファイル]-[新規]-[ソリューション]から、[C#]-[Mobile Apps]-[Blank Apps (Xamarin.Forms Portable)]を選択し、ソリューション名を「AlertDialogSample」として[OK]ボタンを押す。

 AlertDialogSampleプロジェクトに(「空のクラス」テンプレートを使って)MainPage.csファイルを追加し、以下のコードのようにボタンを1つ配置したページを作成する。

C#
……省略……
public class MainPage : ContentPage
{
  public MainPage()
  {
    this.Title = "Main Page";
 
    var buttonDialog1 = new Button
    {
      Text = "Show AlerDialog"
    };
 
    buttonDialog1.Clicked += (sender, e) => 
    {
      // ボタンクリック時の処理は後述する
    };
 
    this.Content = new StackLayout
    {
      Orientation = StackOrientation.Vertical,
      VerticalOptions = LayoutOptions.CenterAndExpand,
      HorizontalOptions = LayoutOptions.CenterAndExpand,
      Children =
      {
        buttonDialog1,
      }
    };
  }
}
ボタンを1つ配置したページのコード(MainPage.cs)

 App.csファイルのGetMainPageメソッドでは、次のコード例のようにMainPageオブジェクトをコンストラクターに指定したNavigationPageオブジェクト(=画面遷移したいときに使う)を返すようにする。NavigationPageを使用している理由は後述する。

C#
public class App
{
  public static Page GetMainPage()
  {   
    return new NavigationPage(new MainPage());
  }
}
メインページを返すGetMainPageメソッドのコード(App.cs)

2. 単純なアラートダイアログを表示する

 MainPageクラスのbuttonDialog1ボタンが押された時に、アラートダイアログを表示するコードは以下のようになる。

C#
……省略……
public class MainPage : ContentPage
{
  public MainPage()
  {
    ……省略……
    buttonDialog1.Clicked += async (sender, e) => 
    {
      var accepted = await this.DisplayAlert(
        "ダイアログのタイトル", "ダイアログの文字列", "はい", "いいえ");
      if (accepted)
      {
        buttonDialog1.Text = "Accepted!";
      }
    };
    ……省略……
  }
}
[Show AlertDialog]ボタンが押された時にアラートダイアログを表示するコード(MainPage.cs)

 ここまでのプログラムをiOSとAndroidで実行し、[Show AlertDialog]ボタンを押すと、次の画面のようになる。

単純なアラートダイアログの表示結果

3. 選択形式のダイアログを表示する

 次に、3つ以上の項目から1つの項目を選択するダイアログを表示する。

 buttonDialog2ボタンを追加し、次のコードのように追記する。

C#
……省略……
public class MainPage : ContentPage
{
  public MainPage()
  {
    ……省略……
 
    var buttonDialog2 = new Button
    {
      Text = "Show ActionSheet"
    };
 
    buttonDialog2.Clicked +=  async (sender, e) => 
    {
      var selectedText = await this.DisplayActionSheet(
        "ダイアログのタイトル", "閉じる", "破棄する", 
        new string[] {"りんご", "すいか", "ぶどう"});
 
      if (selectedText != null)
      {
        buttonDialog2.Text = selectedText;
      }
    };
 
    this.Content = new StackLayout
    {
      ……省略……
      Children =
      {
        buttonDialog1,
        buttonDialog2, 
      }
    };
  }
}
[Show ActionSheet]ボタンが押された時に選択形式のダイアログを表示するコード(MainPage.cs)

 上記のコードを見ると分かるように、3つ以上の項目の選択はPageオブジェクトのDisplayActionSheetメソッドで行う。このメソッドの最終引数に項目を文字列の配列で設定する。戻り値はTask<string>型であり、選択された項目値がそのまま返却される(「閉じる」や「破棄」も文字列として返されるのに違和感を覚えるが、仕方ないところだろう)。

 ここまでのプログラムをiOSとAndroidで実行し、[Show ActionSheet]ボタンを押すと、次の画面のようになる。

選択形式のダイアログの表示結果

【コラム】「閉じる」と「破棄する」

 DisplayActionSheetメソッドの第2引数cancelと第3引数destructionは、一見同じ意味に見えるが、これはiOSのUIActionSheetクラスに由来するもので、cancelがダイアログを閉じる目的なのに対し、destructionは、何らかのデータを破棄する、削除するといった注意を要する処理に使われる。そのため、destructionのボタンは他のボタンよりも目立つように表示される。Androidのダイアログにはこの概念はないが、Xamarin.FormsのAndroid実装により、iOSと同じ機能を実現していると思われる。

4. 処理中のインジケーターを表示する

 Xamarin.Formsには、処理中を示すインジケーターを表示する機能も用意されている。

 ダイアログではないが、ここで解説しよう。

C#
……省略……
public class MainPage : ContentPage
{
  public MainPage()
  {
    ……省略……
 
    var buttonIndicator = new Button
    {
      Text = "Toggle Indicator"
    };
 
    buttonIndicator.Clicked += (sender, e) => 
    {
      this.IsBusy = !this.IsBusy;
    };
 
    this.Content = new StackLayout
    {
    ……省略……
      Children =
      {
        buttonDialog1,
        buttonDialog2,
        buttonIndicator,
      }
    };
  }
}
処理中を示すインジケーターを表示するコード/ボタンクリックで表示が切り替わる(MainPage.cs)

 PageオブジェクトのIsBusyプロパティにtrueを設定するとインジケーターが表示される。

 ここまでのプログラムをiOSとAndroidで実行し、[Toggle Indicator]ボタンを押すと、次の画面のようになる。

インジケーターの表示結果
インジケーターの表示結果

 IsBusyプロパティはiOSのUIApplicationクラスのnetworkActivityIndicatorVisibleプロパティをラップしたものだ。Androidでは、ActionBarProgressBarが表示されるよう実装されている。そのため、ActionBarを非表示にするとAndroidでは効果のないプロパティになってしまう。App.csファイルでNavigationPageを使用しているのはこのためだ。

まとめ

 Xamarin.Formsは、単純なダイアログボックス(DisplayAlertDisplayActionSheet)やインジケーター(IsBusy)を表示するAPIを提供する。

 これら以外のダイアログを表示したい場合には、独自に実装する必要がある。その実装方法を次回のTipsで説明する。

※以下では、本稿の前後を合わせて5回分(第7回~第11回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

7. Xamarin.AndroidでActivityとXamarin.Formsを併用するには?

iOSの場合と同じように、Androidアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。また、iOSとの挙動の違いやフラグメントとの併用についても言及する。

8. Xamarin.Formsからプラットフォーム固有の機能を利用するには?(DependencyService利用)

UIを共通化するフレームワーク「Xamarin.Forms」で、「DependencyService」機能を使用してiOS/Androidの各プラットフォーム固有の機能を実装する方法を解説する。

9. 【現在、表示中】≫ Xamarin.Formsでダイアログボックス(とBusyインジケーター)を表示するには?

ダイアログ(=iOSのUIAlertView/AndroidのAlertDialog)や、処理実行中を示すBusyインジケーターを、Xamarin.Formsで表示する方法を解説する。これらは共通のAPIを使って実装できる。

10. Xamarin.Formsでカスタムダイアログを表示するには?(MessagingCenter利用)

Xamarin.Formsで共通のAPIが提供されているダイアログ(=iOSのUIAlertView/AndroidのAlertDialog)以外のプラットフォーム個別のダイアログを表示する方法を解説。その呼び出しにはMessagingCenterが利用できる。

11. Xamarin Studio(Mac版)で複数のソリューションを開く/複数起動するには?

Macで開発中に、複数のソリューションをXamarin Studioで開く方法と、複数のXamarin Studioを立ち上げる方法を説明する。

サイトからのお知らせ

Twitterでつぶやこう!