10 Ekim 2018 Çarşamba

Adding custom gestures to Xamarin.Forms VisualElements with Renderer


Tek yapmak istediğim label'ıma uzun basılı tuttuktan sonra içindeki text'in kopyalanmasıydı. Haliyle gesture'lara baktım ancak xamarin.forms içinde hali hazırda "longtap" gibi bir gesturerecognizer olmadığını gördüm..


Haliyle ben de "LAYN!" deyip özel, uzun basılabiliritesi olan bir label yaptım. :) Güzel örneği bulunca hepsini ekleyesim de geldi ama sonra dedim boşver mono, zaten örnek var starla geç.
Hemen unutmadan kaynağı ekleyeyim;


Forms;
using System;
using Xamarin.Forms;

namespace GestureRendererSample
{
    public class MyLabel : Label
    {
        public MyLabel()
        {
        }
        public Action OnLongTap { get; set; }
    }
}

Android;

LabelRenderer;
using System;
using Android.Content;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(MyLabel), typeof(MyLabelRenderer))]
namespace GestureRendererSample.Droid
{
    public class MyLabelRenderer : LabelRenderer
    {
        private readonly GestureListener _listener;
        private readonly GestureDetector _detector;

        public MALabelRenderer(Context context) : base(context)
        {
            _listener = new GestureListener();
            _detector = new GestureDetector(context, _listener);
            #region LongPressedtoLabel
            //Bu kısım biraz eksik kaldı maalesef acele iş fln durumları. En hızlı çözümü messaging center ile buldum, tabii ki geçici :)
            MessagingCenter.Unsubscribe<string>(string.Empty, "LongPressedtoLabel");
            MessagingCenter.Subscribe<string>(string.Empty, "LongPressedtoLabel",
            (sender) =>
            {
                try
                {
                    var control = ((MALabel)this.Element);
                    if (control?.OnLongTap != null)
                    {
                        control.OnLongTap();
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.LogError(ex);
                }
            });

            #endregion
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null)
            {
                this.GenericMotion -= HandleGenericMotion;
                this.Touch -= HandleTouch;
            }

            if (e.OldElement == null)
            {
                this.GenericMotion += HandleGenericMotion;
                this.Touch += HandleTouch;
            }
        }

        void HandleTouch(object sender, TouchEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }

        void HandleGenericMotion(object sender, GenericMotionEventArgs e)
        {
            _detector.OnTouchEvent(e.Event);
        }
    }
}


GestureListener;
using System;
using Android.Views;

namespace GestureRendererSample.Droid
{
public class GestureListener : GestureDetector.SimpleOnGestureListener
{
public override void OnLongPress(MotionEvent e)
{
MessagingCenter.Send(string.Empty, "LongPressedtoLabel");
base.OnLongPress(e);
}

public override bool OnDoubleTap(MotionEvent e)
{
return base.OnDoubleTap(e);
}

public override bool OnDoubleTapEvent(MotionEvent e)
{
return base.OnDoubleTapEvent(e);
}

public override bool OnSingleTapUp(MotionEvent e)
{
return base.OnSingleTapUp(e);
}

public override bool OnDown(MotionEvent e)
{
return base.OnDown(e);
}

public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
return base.OnFling(e1, e2, velocityX, velocityY);
}

public override bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
return base.OnScroll(e1, e2, distanceX, distanceY);
}

public override void OnShowPress(MotionEvent e)
{
base.OnShowPress(e);
}

public override bool OnSingleTapConfirmed(MotionEvent e)
{
return base.OnSingleTapConfirmed(e);
}
}
}


iOS;
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(MyLabel), typeof(MyLabelRenderer))]
namespace GestureRendererSample.iOS
{
    public class MyLabelRenderer : LabelRenderer
    {
        UILongPressGestureRecognizer longPressGestureRecognizer;

//UIPinchGestureRecognizer pinchGestureRecognizer;
//UIPanGestureRecognizer panGestureRecognizer;
//UISwipeGestureRecognizer swipeGestureRecognizer;
//UIRotationGestureRecognizer rotationGestureRecognizer;

        public MyLabelRenderer()
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            longPressGestureRecognizer = new UILongPressGestureRecognizer(() => {
                var control = ((MyLabel)this.Element);
                if (control?.OnLongTap != null)
                {
                    control.OnLongTap();
                }
            });

//pinchGestureRecognizer = new UIPinchGestureRecognizer(() => Console.WriteLine("Pinch"));
//panGestureRecognizer = new UIPanGestureRecognizer(() => Console.WriteLine("Pan"));
//swipeGestureRecognizer = new UISwipeGestureRecognizer(() => Console.WriteLine("Swipe"));
//rotationGestureRecognizer = new UIRotationGestureRecognizer(() => Console.WriteLine("Rotation"));

            if (e.NewElement == null)
            {
                if (longPressGestureRecognizer != null)
                {
                    this.RemoveGestureRecognizer(longPressGestureRecognizer);
                }

//if (pinchGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(pinchGestureRecognizer);
//}
//if (panGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(panGestureRecognizer);
//}
//if (swipeGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(swipeGestureRecognizer);
//}
//if (rotationGestureRecognizer != null)
//{
// this.RemoveGestureRecognizer(rotationGestureRecognizer);
//}
            }

            if (e.OldElement == null)
            {
                this.AddGestureRecognizer(longPressGestureRecognizer);

//this.AddGestureRecognizer(pinchGestureRecognizer);
//this.AddGestureRecognizer(panGestureRecognizer);
//this.AddGestureRecognizer(swipeGestureRecognizer);
//this.AddGestureRecognizer(rotationGestureRecognizer);
            }
        }
    }
}


Bu da buracıkta duruversin gari