Xamarin.Formsで背景色をグラデーション表示


StackLayout の背景をグラデーション表示してみます。

なぜ ContentPage ではなく StackLayout なのかというと、ContentPage にグラデーションをかけてみたら Xamarin Studio のXAMLプレビューで一部しか背景色が表示されなかったから。

## PCLコード

```c#:GradientStackLayout.cs
using Xamarin.Forms;

namespace MyApp.Views
{
	public class GradientStackLayout : StackLayout
	{
		public static readonly BindableProperty StartColorProperty = BindableProperty.Create(
			"StartColor", typeof(Color), typeof(GradientStackLayout), Color.Transparent
		);

		public static readonly BindableProperty EndColorProperty = BindableProperty.Create(
			"EndColor", typeof(Color), typeof(GradientStackLayout), Color.Transparent
		);

		public Color StartColor {
			get { return (Color)GetValue(StartColorProperty); }
			set { SetValue(StartColorProperty, value); }
		}

		public Color EndColor {
			get { return (Color)GetValue(EndColorProperty); }
			set { SetValue(EndColorProperty, value); }
		}
	}
}
```

```xml:MainPage.xaml
<?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:views="clr-namespace:MyApp.Views"
	x:Class="MyApp.Views.MainPage">

	<views:GradientStackLayout StartColor="Navy" EndColor="White">
		<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
			<Label Text="MainPage" />
		</StackLayout>
	</views:GradientStackLayout>

</ContentPage>
```

## カスタムレンダラー

### iOS

```c#:GradientStackLayoutRenderer.cs
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

using CoreGraphics;
using CoreAnimation;

using MyApp.Views;
using MyApp.iOS;

[assembly:ExportRenderer(typeof(GradientStackLayout), typeof(GradientStackLayoutRenderer))]

namespace MyApp.iOS
{
	public class GradientStackLayoutRenderer : VisualElementRenderer<GradientStackLayout>
	{
		public override void Draw(CGRect rect)
		{
			base.Draw(rect);

			CAGradientLayer layer = new CAGradientLayer();
			layer.Frame = rect;
			layer.Colors = new CGColor[] {
				Element.StartColor.ToCGColor(),
				Element.EndColor.ToCGColor()
			};
			Layer.InsertSublayer(layer, 0);
		}
	}
}
```


### Android

```c#:GradientStackLayoutRenderer.cs
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

using Android.Graphics;

using Color = Xamarin.Forms.Color;

using MyApp.Views;
using MyApp.Droid;

[assembly:ExportRenderer(typeof(GradientStackLayout), typeof(GradientStackLayoutRenderer))]

namespace MyApp.Droid
{
	public class GradientStackLayoutRenderer : VisualElementRenderer<GradientStackLayout>
	{
		protected override void DispatchDraw(Android.Graphics.Canvas canvas)
		{
			LinearGradient gradient = new LinearGradient(
				0,								// X軸始点
				0,								// Y軸始点
				0,								// X軸終点
				Height,							// Y軸終点
				Element.StartColor.ToAndroid(),	// 開始色
				Element.EndColor.ToAndroid(),	// 終了色
				Shader.TileMode.Mirror			// 範囲外の描画方法
			);

			Paint paint = new Paint {
				Dither = true
			};
			paint.SetShader(gradient);

			canvas.DrawPaint(paint);

			base.DispatchDraw(canvas);
		}
	}
}
```

## 結果

### iOS

![result_ios.png](https://qiita-image-store.s3.amazonaws.com/0/169798/0137bb50-23d1-903e-5f2e-7eca0d2ce02c.png "result_ios.png")

### Android

![result_android.png](https://qiita-image-store.s3.amazonaws.com/0/169798/0ed0b833-b249-a143-5dae-ca2f76d9ff18.png "result_android.png")


グラデーション表示されました。
とりあえずは以上です。


## こちらを参考にしました
Gradient as background color
https://forums.xamarin.com/discussion/22440/gradient-as-background-color