Poli97
Poli97

Reputation: 304

Xamarin form pangesture drag and drop flickering

What I want is to create a box that I can drag around the screen, so I created a class that extend Frame (but it could be also an AbsoluteLayout, NOT a BoxView because I need to write something inside that box).

CLASS DragBox

using System;
using System.Diagnostics;
using Xamarin.Forms;

namespace PanGesture
{
    public class DragBox : Frame
    {
        public DragBox()
        {
            var panGesture = new PanGestureRecognizer();
            this.GestureRecognizers.Add(panGesture);
            panGesture.PanUpdated += OnPanUpdated;
            BorderColor = Color.Blue;
            Padding = 4;
            BackgroundColor = Color.Green;
            Content = new Label
            {
                Text = "Word",
            };
        }

        private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
        {
            switch (e.StatusType)
            {
                case GestureStatus.Started:
                    Debug.WriteLine("DEBUG: start dragging");
                    break;
                case GestureStatus.Running:
                    this.TranslationX = e.TotalX;
                    this.TranslationY = e.TotalY;
                    break;
                case GestureStatus.Completed:
                    Debug.WriteLine("DEBUG: drag ended");
                    break;
            }
        }
    }
}

And in the homepage I just create an instance of DragBox (container is the reference to the AbsoluteLayout on the main page

public partial class HomePage : ContentPage
{
    public HomePage ()
    {
       InitializeComponent ();
       DragBox box = new DragBox();
       AbsoluteLayout.SetLayoutBounds(box, new Rectangle(0.1, 0.1, 0.2, 0.2));
       AbsoluteLayout.SetLayoutFlags(box, AbsoluteLayoutFlags.All);
       container.Children.Add(box);
    }
}

The problem is that when I start to drag the box, it has that effect of flickering as you can see in the image below. How to solve that? Or are there any other way to create a draggable element?

enter image description here

Upvotes: 0

Views: 889

Answers (2)

Cherry Bu - MSFT
Cherry Bu - MSFT

Reputation: 10356

I use your code but I don't have the same issue as you, so I suggest you can try the following code in OnPanUpdated event.

private double  _xOffset, _yOffset;

 private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Started:
                
                Debug.WriteLine("DEBUG: start dragging");
                break;
            case GestureStatus.Running:

               
                this.TranslationX = _xOffset + e.TotalX;
                this.TranslationY = _yOffset + e.TotalY;
               
                break;
            case GestureStatus.Completed:

                _xOffset = this.TranslationX;

                _yOffset = this.TranslationY;
               

                Debug.WriteLine("DEBUG: drag ended");
                break;
        }
    }

Update:

I think you may have some issue in PanContainer, please modify you code as follows:

public class PanContainer : ContentView
{
   
    private double x, y;
    public PanContainer()
    {
        var panGesture = new PanGestureRecognizer();
        
        panGesture.PanUpdated += OnPanUpdated;
        this.GestureRecognizers.Add(panGesture);                          
    }

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Started:
                
                Debug.WriteLine("DEBUG: start dragging");
                break;
            case GestureStatus.Running:
                
                Content.TranslationX = x + e.TotalX;
                Content.TranslationY = y + e.TotalY;

                break;
            case GestureStatus.Completed:
            
                x = Content.TranslationX;
                y = Content.TranslationY;

                Debug.WriteLine("DEBUG: drag ended");
                break;
        }
    }
}

Then ContentPage.cs:

 public partial class Page1 : ContentPage
{
    public Page1()
    {
        InitializeComponent();
        Label label = new Label() { Text = "Hello world" ,BackgroundColor=Color.Green, WidthRequest=100,HeightRequest=150};
        PanContainer box = new PanContainer();
        box.Content = label;
       
        container.Children.Add(box);
    }
}   

You can not drag and drop PanContainer, you just can move PanContainer's content, like this:

enter image description here

Upvotes: 1

Ganesan VG
Ganesan VG

Reputation: 176

Instead of using the TranslateX and TranslateY, use the LayoutTo method like below.

private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
   switch (e.StatusType)
   {
      case GestureStatus.Started:
          break;
      case GestureStatus.Running:
          var newRectangle = new Rectangle(e.TotalX, e.TotalY, this.Bounds.Width, this.Bounds.Height);
          this.LayoutTo(newRectangle, easing: Easing.Linear);
          break;
      case GestureStatus.Completed:
         break;
    }
}

Now there is no flickering.

Upvotes: 0

Related Questions