前回はカスタムレンダラーを利用して実現しましたが、カスタムレンダラーの実装は iOS や Android の知識が求められます。
両方ともまったく知らないワタシには手に負えません。
なので、今回はクロスプラットフォームの画像描画パッケージである FFImageLoadingというものを使って、カスタムレンダラーを使わずに実装してみます。
FFImageLoadingを追加
各プラットフォームに、下記のパッケージを追加します。
- FFImageLoading Plugin for Xamarin Forms
- FFImageLoading Transformations
実装
PCL
Image の代わりに FFImageLoading が提供する CachedImage というクラスを継承して、カスタムコントロールを作成します。
TintImage.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using FFImageLoading.Forms;
using FFImageLoading.Transformations;
using FFImageLoading.Work;
namespace MyApp
{
public class TintImage : CachedImage
{
TintTransformation _Tint;
public TintImage()
{
_Tint = new TintTransformation {
EnableSolidColor = true
};
}
private void ApplyTransformations()
{
Transformations = new List<ITransformation> {
_Tint
};
}
protected void OnTintColorChanged()
{
_Tint.R = (int)(TintColor.R * 255);
_Tint.G = (int)(TintColor.G * 255);
_Tint.B = (int)(TintColor.B * 255);
_Tint.A = (int)(TintColor.A * 255);
ApplyTransformations();
}
public static readonly BindableProperty TintColorProperty = BindableProperty.Create(
"TintColor", typeof(Color), typeof(TintImage), Color.Default,
propertyChanged: (bindable, oldValue, newValue) => ((TintImage)bindable).OnTintColorChanged()
);
public Color TintColor {
get { return (Color)GetValue(TintColorProperty); }
set { SetValue(TintColorProperty, value); }
}
}
}
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:local="clr-namespace:MyApp"
x:Class="MyApp.MyAppPage">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<local:TintImage Source="sample.png" HeightRequest="48" />
<local:TintImage Source="sample.png" HeightRequest="48" TintColor="Red"/>
<local:TintImage Source="sample.png" HeightRequest="48" TintColor="Blue" />
</StackLayout>
</ContentPage>
iOS
FFImageLoading の初期化コードを追加します。
AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using FFImageLoading.Forms.Touch; // <-- 追加
namespace MyApp.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
CachedImageRenderer.Init(); // <-- 追加
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}
Android
FFImageLoading の初期化コードを追加します。
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using FFImageLoading.Forms.Droid; // <-- 追加
namespace MyApp.Droid
{
[Activity(Label = "MyApp.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
CachedImageRenderer.Init(); // <-- 追加
LoadApplication(new App());
}
}
}
結果
iOS
Android
カスタムレンダラーを使わずに TintColor を設定できました。
これは助かりますね。
とりあえずは以上です。