今回はXamarin.Forms Pickerの右端に画像を表示する方法についてです。
Rendererを使うことで実装できます。
1.iOSのResourcesフォルダとAndroidのdrawableフォルダ内に画像(今回はpicker_image.pngという画像)を追加
2.CustomPickerを共通プロジェクトに追加
using System;
using Xamarin.Forms;
namespace testPrj {
public class CustomPicker : Picker {
public CustomPicker(){}
public static readonly BindableProperty ImageProperty =
BindableProperty.Create(nameof(Image), typeof(string), typeof(CustomPicker), string.Empty);
public string Image {
get { return (string)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly BindableProperty ImageWidthProperty =
BindableProperty.Create(nameof(ImageWidth), typeof(double), typeof(CustomPicker),10d);
public double ImageWidth {
get { return (double)GetValue(ImageWidthProperty); }
set { SetValue(ImageWidthProperty, value); }
}
public static readonly BindableProperty ImageHeightProperty =
BindableProperty.Create(nameof(ImageHeight), typeof(double), typeof(CustomPicker), 10d);
public double ImageHeight {
get { return (double)GetValue(ImageHeightProperty); }
set { SetValue(ImageWidthProperty, value); }
}
}
}
3.iOSプロジェクトにCustomPickerのレンダラーを追加
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using testPrj.iOS;
using testPrj;
using CoreGraphics;
[assembly: ExportRenderer(typeof(CustomPicker), typeof(CustomPickerRenderer))]
namespace testPrj.iOS {
public class CustomPickerRenderer : PickerRenderer {
public CustomPickerRenderer() {}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) {
base.OnElementChanged(e);
if (Control != null) {
var element = (CustomPicker)Element;
if (!string.IsNullOrWhiteSpace(element.Image)) {
var uIImageView = new UIImageView(new UIImage(element.Image));
uIImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
uIImageView.Frame = new CGRect(0, 0, element.ImageWidth, element.ImageHeight);
var uiView = new UIView(new CGRect(0, 0, element.ImageWidth, element.ImageHeight));
uiView.BackgroundColor = UIColor.Clear;
uiView.AddSubview(uIImageView);
Control.RightView = uiView;
Control.RightViewMode = UITextFieldViewMode.Always;
}
}
}
}
}
4.AndroidプロジェクトにCustomPickerのレンダラーを追加
using testPrj;
using testPrj.Droid;
using Xamarin.Forms;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Support.V4.Content;
using Xamarin.Forms.Platform.Android;
using Android.Content;
[assembly: ExportRenderer(typeof(CustomPicker), typeof(CustomPickerRenderer))]
namespace testPrj.Droid {
public class CustomPickerRenderer : PickerRenderer {
CustomPicker element;
public CustomPickerRenderer(Context context) : base(context) {}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) {
base.OnElementChanged(e);
element = (CustomPicker)this.Element;
if (Control != null && this.Element != null && !string.IsNullOrEmpty(element.Image))
Control.Background = SetBackground(element.Image, element.ImageWidth, element.ImageHeight);
}
public LayerDrawable SetBackground(string imagePath, double imageWidth, double imageHeight) {
Drawable[] layers = { GetDrawable(imagePath, imageWidth, imageHeight) };
LayerDrawable layerDrawable = new LayerDrawable(layers);
layerDrawable.SetLayerInset(0, 0, 0, 0, 0);
return layerDrawable;
}
private BitmapDrawable GetDrawable(string imagePath, double imageWidth, double imageHeight) {
int resID = Resources.GetIdentifier(imagePath, "drawable", this.Context.PackageName);
var drawable = ContextCompat.GetDrawable(this.Context, resID);
var bitmap = ((BitmapDrawable)drawable).Bitmap;
var context = Xamarin.Essentials.Platform.AppContext;
var resources = context.Resources;
var result = new BitmapDrawable(Resources, Bitmap.CreateScaledBitmap(bitmap, (int)(imageWidth * resources.DisplayMetrics.Density), (int)(imageHeight * resources.DisplayMetrics.Density), true));
result.Gravity = Android.Views.GravityFlags.Right;
return result;
}
}
}
5.CustomPickerをImage,ImageWidth,ImageHeightを指定して使用する
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="test1.MainPage"
xmlns:local="clr-namespace:test1">
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<local:CustomPicker
Margin="20,10"
Image="picker_image"
ImageWidth="40"
ImageHeight="20"
BackgroundColor="LightGray"
VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand"
HeightRequest="50"/>
</StackLayout>
</ContentPage>
↓iOS
↓Android