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;
}
}
现在没有闪烁了。
我想要创建一个可以在屏幕上拖动的框,所以我创建了一个扩展 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;
}
}
现在没有闪烁了。