简体   繁体   中英

Gesture image in Xamarin Forms

I know there are like 2 gesturelisteners (zoom and tap ) in Xamarin.Forms. I want to know an example of how to do pan of image? I am trying to implement a way where we register a gesture and then move position of the image based on where you have moved.

I am using an imagerenderer. It do however work, but there seems to give me a funny blur effect. It seems that I cannot change the X and Y coordinates from the Image rather than that we can change it on the imagerenderer

I hope people can help a n00b in Xamarin.Forms to implement a good panimagegesture.

PanImageGesture:

public class PanGestureImage : Image
{
    public PanGestureImage()
    {

    }

    public event EventHandler GestureEvent;

    public void OnGestureEvent(float x, float y)
    {

    }
}

Native android pan image renderer:

[assembly: ExportRenderer(typeof(PanGestureImage), typeof(GestureImageRenderer))]
namespace Test.Droid.Renderer
{
    public class GestureImageRenderer : ImageRenderer
    {
        private readonly PanGestureListener _listener;
        private readonly GestureDetector _detector;

        public GestureImageRenderer()
        {
            _listener = new PanGestureListener();
            _detector = new GestureDetector(_listener);
        }

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

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

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

            }
        }

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

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

        void HandleGestureEvent(object sender, EventArgs e)
        {
            PanGestureImage _gi = (PanGestureImage)this.Element;
            var simpleGesture = sender as PanGestureListener;
            _gi.OnGestureEvent(simpleGesture.DiffX, simpleGesture.DiffY);
            MoveImage(sender);
        }

        private void MoveImage(object sender)
        {
            var simpleGesture = sender as PanGestureListener;
       //     this.SetX(simpleGesture.DiffX);
       //     this.SetY(simpleGesture.DiffY);

        }
    }
}

PanGestureListener:

public class PanGestureListener : GestureDetector.SimpleOnGestureListener
{
    private static int SWIPE_THRESHOLD = 100;
    private static int SWIPE_VELOCITY_THRESHOLD = 100;

    public event EventHandler GestureEvent;

    public float DiffX { get; set; }
    public float DiffY { get; set; }

    /*
    public override bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    {

        DiffY = e2.GetY() - e1.GetY();
        DiffX = e2.GetX() - e1.GetX();
        if (GestureEvent != null)
        {
            GestureEvent(this, null);
        }
        return base.OnFling(e1, e2, velocityX, velocityY);
    } */


    public override bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
    {

        DiffY = e2.GetY() - e1.GetY();
        DiffX = e2.GetX() - e1.GetX();
        if (GestureEvent != null)
        {
            GestureEvent(this, null);
        }
         return base.OnScroll(e1, e2, distanceX, distanceY);
    }
}

Usages in XAML:

<StackLayout VerticalOptions="CenterAndExpand">
  <AbsoluteLayout>
    <renderer:PanGestureImage Source="container.png"
           AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
           AbsoluteLayout.LayoutFlags="All">
    </renderer:PanGestureImage>
    <Image Source="crosshair.png"
           AbsoluteLayout.LayoutBounds="0.5, 0.5,0.1,0.1"
           AbsoluteLayout.LayoutFlags="All"/>
  </AbsoluteLayout>
</StackLayout>

You could use FFImageLoading for that. If you want to test it just clone repo and build the sample app. In samples it uses buttons (samples are tested with older Forms version which doesn't have PinchGestureRecognizer) but it should be easily migrated to PinchGestureRecognizer.

Basically all you need to do is to set CropTransformation for CachedImage instance with appropriate parameters public CropTransformation(double zoomFactor, double xOffset, double yOffset, double cropWidthRatio, double cropHeightRatio) . You can get a jpg or png file after transformation with CachedImage GetImageAsJPG or GetImageAsPNG methods Sample code (it's really easy):

CropTransformationPage.cs

CropTransformationViewModel.cs

在此处输入图片说明 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM