Xamarin.Formsでトースト通知を出力する方法

Xamarin.Formsでトースト通知を出力する方法をご紹介します。
「DependencyService」を用いて実装します。

条件

  • Xamarin.Forms
  • Visual Studio 2019
  • SHARP SH-M12(Android 9.0 – API 28)

トースト通知とは?

トースト通知(Toast Notification)とは、画面にポップアップ表示され、一定時間が経過すると自動的に消える簡易メッセージです。
ユーザが実行した操作に対して、アプリの実行結果を通知すること等に使用されます。
例:「○○を登録しました。」「○○を削除しました。」

DependencyServiceとは?

DependencyService クラスは、Xamarin.Forms アプリケーションで共有コードからネイティブ プラットフォームの機能を起動できるようにするサービス ロケーターです。
プラットフォームの実装を DependencyService に登録し、共有コードから解決してそれらを呼び出す必要があります。
出典:Xamarin.Forms の DependencyService

以下の手順で実装します。

  1. 共有コードにインターフェースの作成
  2. 各プラットフォーム(Android、iOS)でインターフェイスの実装
    • プラットフォームの実装の登録
  3. プラットフォームの実装の解決
    • 共有コード内でGet<T> メソッドを呼び出し

実装

共有コードにインターフェースの作成

共通プロジェクトにインターフェースを追加します。

IMessage.cs

以下のように記述します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
namespace Toast
{
/**
* toastメッセージ用のインターフェース
* */
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
}
namespace Toast { /** * toastメッセージ用のインターフェース * */ public interface IMessage { void LongAlert(string message); void ShortAlert(string message); } }
namespace Toast
{
    /**
     * toastメッセージ用のインターフェース
     * */
    public interface IMessage
    {
        void LongAlert(string message);
        void ShortAlert(string message);
    }
}

各プラットフォーム(Android、iOS)でインターフェイスの実装

各プラットフォームのプロジェクトにクラスを追加します。

また、以下のような記述を行うことで、各プラットフォームのクラスをDependencyServiceで使用できるようにします。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]

Android

MessageAndroid.cs
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using Android.App;
using Android.Widget;
using ToastSample.Droid;
[assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))]
namespace ToastSample.Droid
{
public class MessageAndroid : IMessage
{
public void LongAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
}
public void ShortAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
}
}
}
using Android.App; using Android.Widget; using ToastSample.Droid; [assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))] namespace ToastSample.Droid { public class MessageAndroid : IMessage { public void LongAlert(string message) { Toast.MakeText(Application.Context, message, ToastLength.Long).Show(); } public void ShortAlert(string message) { Toast.MakeText(Application.Context, message, ToastLength.Short).Show(); } } }
using Android.App;
using Android.Widget;
using ToastSample.Droid;

[assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))]
namespace ToastSample.Droid
{
    public class MessageAndroid : IMessage
    {
        public void LongAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
        }

        public void ShortAlert(string message)
        {
            Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
        }
    }
}

iOS

MessageIOS.cs
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using Foundation;
using ToastSample.iOS;
using UIKit;
[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace ToastSample.iOS
{
public class MessageIOS : IMessage
{
const double LONG_DELAY = 3.5;
const double SHORT_DELAY = 2.0;
NSTimer alertDelay;
UIAlertController alert;
public void LongAlert(string message)
{
ShowAlert(message, LONG_DELAY);
}
public void ShortAlert(string message)
{
ShowAlert(message, SHORT_DELAY);
}
void ShowAlert(string message, double seconds)
{
alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
{
dismissMessage();
});
alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
}
void dismissMessage()
{
if (alert != null)
{
alert.DismissViewController(true, null);
}
if (alertDelay != null)
{
alertDelay.Dispose();
}
}
}
}
using Foundation; using ToastSample.iOS; using UIKit; [assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))] namespace ToastSample.iOS { public class MessageIOS : IMessage { const double LONG_DELAY = 3.5; const double SHORT_DELAY = 2.0; NSTimer alertDelay; UIAlertController alert; public void LongAlert(string message) { ShowAlert(message, LONG_DELAY); } public void ShortAlert(string message) { ShowAlert(message, SHORT_DELAY); } void ShowAlert(string message, double seconds) { alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) => { dismissMessage(); }); alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert); UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null); } void dismissMessage() { if (alert != null) { alert.DismissViewController(true, null); } if (alertDelay != null) { alertDelay.Dispose(); } } } }
using Foundation;
using ToastSample.iOS;
using UIKit;

[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace ToastSample.iOS
{
    public class MessageIOS : IMessage
    {
        const double LONG_DELAY = 3.5;
        const double SHORT_DELAY = 2.0;

        NSTimer alertDelay;
        UIAlertController alert;

        public void LongAlert(string message)
        {
            ShowAlert(message, LONG_DELAY);
        }
        public void ShortAlert(string message)
        {
            ShowAlert(message, SHORT_DELAY);
        }

        void ShowAlert(string message, double seconds)
        {
            alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
            {
                dismissMessage();
            });
            alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
        }

        void dismissMessage()
        {
            if (alert != null)
            {
                alert.DismissViewController(true, null);
            }
            if (alertDelay != null)
            {
                alertDelay.Dispose();
            }
        }
    }
}

トースト通知の出力

共有コード内でGet<T> メソッドを呼び出しを行うことで、トースト通知を行います。

MainPage.xaml

例として、ボタンを3つ配置します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Toast.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Button x:Name="btnAdd" Text="追加" Clicked="btnAdd_Clicked" />
<Button x:Name="btnUpdate" Text="更新" Clicked="btnUpdate_Clicked" />
<Button x:Name="btnDelete" Text="削除" Clicked="btnDelete_Clicked" />
</StackLayout>
</ContentPage>
<?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:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Toast.MainPage"> <StackLayout> <!-- Place new controls here --> <Button x:Name="btnAdd" Text="追加" Clicked="btnAdd_Clicked" /> <Button x:Name="btnUpdate" Text="更新" Clicked="btnUpdate_Clicked" /> <Button x:Name="btnDelete" Text="削除" Clicked="btnDelete_Clicked" /> </StackLayout> </ContentPage>
<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Toast.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Button x:Name="btnAdd" Text="追加" Clicked="btnAdd_Clicked" />
        <Button x:Name="btnUpdate" Text="更新" Clicked="btnUpdate_Clicked" />
        <Button x:Name="btnDelete" Text="削除" Clicked="btnDelete_Clicked" />
    </StackLayout>

</ContentPage>

MainPage.xaml.cs

ボタン毎に異なったメッセージを出力するようにします。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace ToastSample
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void btnAdd_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IMessage>().ShortAlert("追加ボタンが押されました。");
}
private void btnUpdate_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IMessage>().ShortAlert("更新ボタンが押されました。");
}
private void btnDelete_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IMessage>().ShortAlert("削除ボタンが押されました。");
}
}
}
using System; using System.ComponentModel; using Xamarin.Forms; namespace ToastSample { // Learn more about making custom code visible in the Xamarin.Forms previewer // by visiting https://aka.ms/xamarinforms-previewer [DesignTimeVisible(false)] public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private void btnAdd_Clicked(object sender, EventArgs e) { DependencyService.Get<IMessage>().ShortAlert("追加ボタンが押されました。"); } private void btnUpdate_Clicked(object sender, EventArgs e) { DependencyService.Get<IMessage>().ShortAlert("更新ボタンが押されました。"); } private void btnDelete_Clicked(object sender, EventArgs e) { DependencyService.Get<IMessage>().ShortAlert("削除ボタンが押されました。"); } } }
using System;
using System.ComponentModel;
using Xamarin.Forms;

namespace ToastSample
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void btnAdd_Clicked(object sender, EventArgs e)
        {
            DependencyService.Get<IMessage>().ShortAlert("追加ボタンが押されました。");
        }

        private void btnUpdate_Clicked(object sender, EventArgs e)
        {
            DependencyService.Get<IMessage>().ShortAlert("更新ボタンが押されました。");
        }

        private void btnDelete_Clicked(object sender, EventArgs e)
        {
            DependencyService.Get<IMessage>().ShortAlert("削除ボタンが押されました。");
        }
    }
}

実行結果

各ボタンが押された場合、指定したメッセージが表示されます。

参考

stackoverflow:Toast equivalent for Xamarin Forms

https://stackoverflow.com/questions/35279403/toast-equivalent-for-xamarin-forms

Microsoft:Xamarin.Forms の DependencyService

https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/app-fundamentals/dependency-service/

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です