前回 は GetureRecognizer と Setter を連携する Behavior を作ることで、タップに反応するコントロールを作りました
今回はさらに発展させて、タップのたびに外観が変わるような実装を試してみたいと思います
例によって修正箇所は上記のみ
まずは 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:b="clr-namespace:XamarinControl.Behaviors;assembly=XamarinControl" x:Class="XamarinControl.Views.TopPage"> <BoxView BackgroundColor="#FFD45D87" WidthRequest="200" HeightRequest="200" HorizontalOptions="Center" VerticalOptions="Center"> <BoxView.Behaviors> <b:GestureRecognizeBehavior> <b:GestureRecognizeBehavior.GestureRecognizer> <TapGestureRecognizer NumberOfTapsRequired="1" /> </b:GestureRecognizeBehavior.GestureRecognizer> <b:GestureRecognizeBehavior.Setters> <Setter Property="BoxView.BackgroundColor" Value="#FFE6855E"/> <Setter Property="BoxView.BackgroundColor" Value="#FFF9DB57"/> <Setter Property="BoxView.BackgroundColor" Value="#FF5EC84E"/> <Setter Property="BoxView.BackgroundColor" Value="#FF42AAC7"/> <Setter Property="BoxView.BackgroundColor" Value="#FF6A8CC7"/> <Setter Property="BoxView.BackgroundColor" Value="#FF9D73BB"/> <Setter Property="BoxView.BackgroundColor" Value="#FFD45D87"/> </b:GestureRecognizeBehavior.Setters> </b:GestureRecognizeBehavior> </BoxView.Behaviors> </BoxView> </ContentPage>
Setters に BackgroundColor を切り替える複数の Setter を追加しています
さらに GestureRecognizeBehavior
/// <summary> /// GestureRecognizer に反応する Behavior /// </summary> public class GestureRecognizeBehavior : Behavior<View> { /// <summary> /// アタッチされた View /// </summary> private View bindable = null; /// <summary> /// 現在のインデックス /// </summary> private int index = 0; /// <summary> /// アタッチされた GestureRecognizer の BindableProperty /// </summary> public static readonly BindableProperty GestureRecognizerProperty = BindableProperty.Create<GestureRecognizeBehavior, TapGestureRecognizer>(p => p.GestureRecognizer, null); /// <summary> /// アタッチされた GestureRecognizer /// </summary> public TapGestureRecognizer GestureRecognizer { get { return (TapGestureRecognizer)this.GetValue(GestureRecognizerProperty); } set { this.SetValue(GestureRecognizerProperty, value); } } /// <summary> /// アタッチされた Setter のリストの BindableProperty /// </summary> public static readonly BindableProperty SettersProperty = BindableProperty.Create<GestureRecognizeBehavior, IList<Setter>>(p => p.Setters, new List<Setter>()); /// <summary> /// アタッチされた Setter のリスト /// </summary> public IList<Setter> Setters { get { return (IList<Setter>)this.GetValue(SettersProperty); } set { this.SetValue(SettersProperty, value); } } /// <summary> /// Behavior がアタッチされた時の処理 /// </summary> /// <param name="bindable">アタッチされた View</param> protected override void OnAttachedTo(View bindable) { base.OnAttachedTo(bindable); this.bindable = bindable; if (this.bindable == null || this.GestureRecognizer == null) { return; } this.GestureRecognizer.Tapped += this.OnGestured; this.bindable.GestureRecognizers.Add(this.GestureRecognizer); } /// <summary> /// GestureRecognizer のイベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="args">イベント引数</param> private void OnGestured(object sender, EventArgs args) { // アタッチされた View に Setter を反映 if (index >= this.Setters.Count) { index %= this.Setters.Count; } var setter = this.Setters[index]; this.bindable.SetValue(setter.Property, setter.Value); index++; } /// <summary> /// Behavior がデタッチされた時の処理 /// </summary> /// <param name="bindable"></param> protected override void OnDetachingFrom(View bindable) { if (this.bindable != null && this.GestureRecognizer != null) { this.bindable.GestureRecognizers.Remove(this.GestureRecognizer); this.GestureRecognizer.Tapped -= this.OnGestured; this.GestureRecognizer = null; this.bindable = null; } base.OnDetachingFrom(bindable); } }
主な変更箇所は下記です
/// <summary> /// GestureRecognizer のイベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="args">イベント引数</param> private void OnGestured(object sender, EventArgs args) { // アタッチされた View に Setter を反映 if (index >= this.Setters.Count) { index %= this.Setters.Count; } var setter = this.Setters[index]; this.bindable.SetValue(setter.Property, setter.Value); index++; }
Behavior が保持している index をもとに対応する Setter を拾って設定しているだけですね
これを実行すると
タップで色が切り替わるようになりました