Xamarin.FormsでStackLayoutの背景グラデーション:メモ
こちらの動画の中のデモアプリケーションでもShellのドロワーっていうのかな,左から出てくるメニューの背景でグラデーションが使われている.
背景にグラデーションをつけるにはカスタムレンダラーを使う必要がある.
ここがわかりやすかった. qiita.com
Androidのコードだけ.
手順としては大まかに以下のとおり.
StackLayoutなどのレイアウト系要素について.
- 各クラスを継承した新しいクラスを作成する.
- グラデーションに使う2色を指定するプロパティ(StartColor,EndColorと名前をつけていることが多い)を追加する.
- CustomRendererを作る.
コントロールを継承したクラスを作る.
ついでにBindingできるようにBindablePropertyにする.
public class GradientStackLayout : StackLayout { public Color StartColor { get { return (Color)GetValue(StartColorProperty); } set { SetValue(StartColorProperty, value); } } public static readonly BindableProperty StartColorProperty = BindableProperty.Create( propertyName: nameof(StartColor), returnType: typeof(Color), declaringType: typeof(GradientStackLayout), defaultValue: Color.Transparent, defaultBindingMode: BindingMode.OneWay, propertyChanged: StartColorPropertyChanged ); private static void StartColorPropertyChanged(BindableObject bindable, object oldValue, object newValue) { //Do something if you need. } public Color EndColor { get { return (Color)GetValue(EndColorProperty); } set { SetValue(EndColorProperty, value); } } public static readonly BindableProperty EndColorProperty = BindableProperty.Create( propertyName: nameof(EndColor), returnType: typeof(Color), declaringType: typeof(GradientStackLayout), defaultValue: Color.Transparent, defaultBindingMode: BindingMode.OneWay, propertyChanged: EndColorPropertyChanged ); private static void EndColorPropertyChanged(BindableObject bindable, object oldValue, object newValue) { //Do something if you need. } public float GradientRatio { get { return (float)GetValue(GradientRatioProperty); } set { SetValue(GradientRatioProperty, value); } } public static readonly BindableProperty GradientRatioProperty = BindableProperty.Create ( propertyName: nameof(GradientRatio), returnType: typeof(float), declaringType: typeof(GradientStackLayout), defaultValue: 1.0f, defaultBindingMode: BindingMode.OneWay, propertyChanged: GradientRatioPropertyChanged ); private static void GradientRatioPropertyChanged(BindableObject bindable, object oldValue, object newValue) { } }
Custom Rendererを作る
[assembly: ExportRenderer(typeof(GradientStackLayout), typeof(GradientStackLayoutRenderer))] namespace CustomRenderer.Droid.Renderers { public class GradientStackLayoutRenderer : VisualElementRenderer<GradientStackLayout> { public GradientStackLayoutRenderer(Context context) : base(context) { } protected override void DispatchDraw(Canvas canvas) { //X軸始点 //Y軸始点 //X軸終点 //Y軸終点 //開始色 //終了色 //範囲外の描画方法 LinearGradient gradient = new LinearGradient ( x0: 0, y0: 0, x1: 0, y1: Height*Element.GradientRatio, color0: Element.StartColor.ToAndroid(), color1: Element.EndColor.ToAndroid(), tile: Shader.TileMode.Clamp ); Paint paint = new Paint { Dither = true, }; paint.SetShader(gradient); canvas.DrawPaint(paint); base.DispatchDraw(canvas); } } }
大事なことは以下の属性部分.
[assembly: ExportRenderer(typeof(GradientStackLayout), typeof(GradientStackLayoutRenderer))]
1つ目の引数で指定されているコントロールGradientStackLayout
に対して2つ目の引数でしたレンダラーを使ってUIコントロールを描画する,という指定.
今回のソースコードはこちら
20200111追記: グラデーションの方向を指定できるようにした.
GradientHorizontalDirectionとGradientVerticalDirectionを追加.