Xamrin.Forms アラートダイアログ(DisplayAlert)に画像を追加する方法を説明します。
1.共通プロジェクトに各OSのダイアログを呼び出すインターフェースを実装
public interface ICustomDisplayAlert {
Task<bool> DisplayAlert(string title, string message,string cancel, string accept, FileImageSource file);
}
2.下記の記事にある手順の2〜3を行う
Xamrin.Forms アラートダイアログ(DisplayAlert)のボタンの文字色の変更方法
Xamrin.Forms アラートダイアログ(DisplayAlert)のボタンの文字色の変え方を説明します。1.共通プロジェクトに各OSのダイアログを呼び出すインターフェースを実装public interface ICu...
3.Androidプロジェクト内にダイアログを表示するクラスを追加
using Xamarin.Forms;
using System.Threading.Tasks;
using TestPrj;
using TestPrj.Droid;
[assembly: Dependency(typeof(CustomDisplayAlert))]
namespace TestPrj.Droid {
public class CustomDisplayAlert : ICustomDisplayAlert {
public CustomDisplayAlert() { }
public Task<bool> DisplayAlert(string title, string message,string cancel, string accept, FileImageSource file) {
var taskComplete = new TaskCompletionSource<bool>();
var alert = new Android.Support.V7.App.AlertDialog.Builder(MainActivity.context, global::TestPrj.Droid.Resource.Style.CustomDialogStyle);
alert.SetTitle(title);
alert.SetMessage(message);
var img = new Image();
img.Source = file;
var imageView = new ImageView(MainActivity.context);
Device.BeginInvokeOnMainThread(async () => {
var bitmap = await ImageSourceToBitmap(img.Source);
imageView.SetImageBitmap(bitmap);
LinearLayout linearLayout = new LinearLayout(MainActivity.context);
linearLayout.Orientation = Orientation.Vertical;
linearLayout.AddView(imageView);
alert.SetView(linearLayout);
if (!string.IsNullOrEmpty(accept)) {
alert.SetPositiveButton(accept, (sender, e) => {
taskComplete.SetResult(true);
});
}
if (!string.IsNullOrEmpty(cancel)) {
alert.SetNegativeButton(cancel, (sender, e) => {
taskComplete.SetResult(false);
});
}
alert.Create().Show();
});
return taskComplete.Task;
}
// ImageSourceをbitmapに変換
async Task<Android.Graphics.Bitmap> ImageSourceToBitmap(ImageSource imageSource) {
IImageSourceHandler handler;
if (imageSource is UriImageSource)
handler = new ImageLoaderSourceHandler();
else if (imageSource is FileImageSource)
handler = new FileImageSourceHandler();
else if (imageSource is StreamImageSource)
handler = new StreamImagesourceHandler();
else
return null;
// 第二引数にはContextが必要。この例ではMainActivity.csにstaticな変数Contextを用意済み
// ここのContextの取り方は好きなように実装してください
return await handler.LoadImageAsync(imageSource, MainActivity.Context);
}
}
}
4.iOSプロジェクト内にダイアログを表示するクラスを追加
using Xamarin.Forms;
using System.Threading.Tasks;
using UIKit;
using TestPrj;
using TestPrj.iOS;
using Foundation;
[assembly: Dependency(typeof(CustomDisplayAlert))]
namespace TestPrj.iOS {
public class CustomDisplayAlert : ICustomDisplayAlert {
public Task<bool> DisplayAlert(string title, string message, string cancel, string accept, FileImageSource file) {
var taskComplete = new TaskCompletionSource<bool>();
UIApplication.SharedApplication.InvokeOnMainThread(() => {
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0)) {
var alertDialog = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
UIView subView = null;
var imageRect = new RectangleF(0f, 0f, 64f, 64f);
var myImage = new UIImageView(imageRect);
myImage.Image = UIImage.FromFile(file);
myImage.Opaque = true;
// タイトル,メッセージが属するsubViewを取得 同階層に画像表示
subView = alertDialog.View.Subviews[0].Subviews[0].Subviews[0].Subviews[0];
subView.AddSubview(myImage);
nfloat temporaryImgX = 103;
subView.AddConstraint(
NSLayoutConstraint.Create(
subView,
NSLayoutAttribute.Height,
NSLayoutRelation.Equal,
null,
NSLayoutAttribute.NoAttribute,
1,
165
)
);
var imgY = 165 - 64 - 11;
//表示位置を変更
myImage.Frame = new CGRect(x: temporaryImgX, y: imgY, width: 64, height: 64);
alertDialog.AddAction(UIAlertAction.Create(accept, UIAlertActionStyle.Destructive, x => {
taskComplete.SetResult(true);
}));
alertDialog.AddAction(UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, x => {
taskComplete.SetResult(false);
}));
// ダイアログを表示
var ctl = GetViewController(UIApplication.SharedApplication.Windows);
if (ctl != null) {
ctl.PresentViewController(alertDialog, true, () => {
if (subView != null && subView.Subviews.Length > 1) {
nfloat dialogWidth = subView.Bounds.Width;
nfloat imgX = dialogWidth / 2 - subView.Subviews[1].Bounds.Width / 2;
// 表示位置を変更
if (temporaryImgX != imgX) {
myImage.Frame = new CGRect(x: imgX, y: imgY, width: 64, height: 64);
}
}
});
}
}
});
return taskComplete.Task;
}
UIViewController GetViewController() {
var rootViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
if (rootViewController.PresentedViewController == null)
return rootViewController;
if (rootViewController.PresentedViewController is UINavigationController)
return ((UINavigationController)rootViewController.PresentedViewController).VisibleViewController;
if (rootViewController.PresentedViewController is UITabBarController)
return ((UITabBarController)rootViewController.PresentedViewController).SelectedViewController;
return rootViewController.PresentedViewController;
}
}
}
5.呼び出して使う
await DependencyService.Get<ICustomDisplayAlert>().DisplayAlert("title", "message", "cancel", "OK", ImageFile) ;