Xamarin 形式 pangesture 拖放闪烁

Xamarin form pangesture drag and drop flickering

我想要创建一个可以在屏幕上拖动的框,所以我创建了一个扩展 Frame 的 class(但它也可以是 AbsoluteLayout,不是 BoxView 因为我需要在那个盒子里写点东西)。

CLASS 拖拽框

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;
            }
        }
    }
}

并且在主页中我只是创建了一个 DragBox 的实例 (container 是对首页AbsoluteLayout的引用

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);
    }
}

问题是,当我开始拖动框时,它会出现闪烁的效果,如下图所示。 如何解决?或者还有其他方法可以创建可拖动元素吗?

我使用了你的代码,但我没有遇到和你一样的问题,所以我建议你可以在 OnPanUpdated 事件中尝试以下代码。

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;
        }
    }

更新:

我觉得你的 PanContainer 可能有问题,请修改你的代码如下:

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;
        }
    }
}

然后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);
    }
}   

您不能拖放 PanContainer,您只能移动 PanContainer 的内容,如下所示:

不使用 TranslateX 和 TranslateY,而是使用如下所示的 LayoutTo 方法。

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;
    }
}

现在没有闪烁了。