Edited at

Xamarin.FormsでImageをボタンっぽくする

More than 1 year has passed since last update.


Buttonコントロール

Xamarin.FormsにはちゃんとButtonというコントロールがあって、それのImageプロパティに画像パスを指定することで画像をボタンにすることができます。


a.xaml

<Button Image="image.png" Clicked="Clicked"/>


しかし、これを使うといろいろめんどくさい(具体的には画像のサイズ変更など)のでImageコントロールをボタンぽくしてみようと思いコントロールを作成しました。


ボタンっぽいImageコントロール


ImageButton.cs

public class ImageButton: Image

{
public event EventHandler Tapped;

/// <summary>
/// アニメーション時間を取得または設定します。
/// (デフォルト100ms)
/// </summary>
/// <value>アニメーション時間</value>
public uint? AnimationTime { get; set; }

/// <summary>
/// アニメーションの際のスケールを取得または設定します。
/// (デフォルト0.5)
/// </summary>
/// <value>アニメーションの際のスケール</value>
public double? UnevennessScale { get; set; }

public ImageButton(): base()
{
var tgr = new TapGestureRecognizer();
tgr.Tapped += (sender, e) => OnClicked(sender, e);
this.GestureRecognizers.Add(tgr);
}

private async void OnClicked(object sender, EventArgs e)
{
var btn = sender as ImageButton;

if (btn != null)
{
uint _animationTime;
double _unevennessScale;

// アニメーション時間の指定がなければデフォルト(100ms)
if (AnimationTime is null)
{
_animationTime = 100;
}
else
{
_animationTime = (uint)AnimationTime;
}

//凹凸スケールの指定がなければデフォルト値(0.5)
if (UnevennessScale is null)
{
_unevennessScale = 0.5;
}
else
{
_unevennessScale = (double)UnevennessScale;
}

await btn.ScaleTo(_unevennessScale, _animationTime);
await btn.ScaleTo(1, _animationTime);
}

// アニメーション後に指定されたメソッドを実行
if (Tapped != null)
{
Tapped(this, e);
}
}
}


ポイントはImageコントロールにしてしまうとButtonコントロールのような「押された感」がなくなってしまうので、アニメーションをつけており、そのパラメータはカスタム可能です。(デフォルトでは押すと0.5倍の大きさになって「押された感」を演出)

XAML側では以下のように使えます。


デフォルト.xaml

<control:ImageButton Source="image.png" Tapped="Clicked" />



カスタム.xaml

<control:ImageButton Source="image.png" Tapped="Clicked" AnimationTime="500" UnevennessScale="0.5" />



さいごに

とりあえず作ってみましたが、もっとこうするといいなどアドバイスいただけると嬉しいです。