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
以下の手順で実装します。
- 共有コードにインターフェースの作成
- 各プラットフォーム(Android、iOS)でインターフェイスの実装
- プラットフォームの実装の解決
実装
共有コードにインターフェースの作成
共通プロジェクトにインターフェースを追加します。

IMessage.cs
以下のように記述します。
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で使用できるようにします。
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]
[assembly: Xamarin.Forms.Dependency(typeof(クラス名))]
Android

MessageAndroid.cs
[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
[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;
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) =>
alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
alert.DismissViewController(true, null);
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つ配置します。
<?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"
x:Class="Toast.MainPage">
<!-- 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" />
<?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
ボタン毎に異なったメッセージを出力するようにします。
using System.ComponentModel;
// 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
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/