Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xamarin pan手势识别器无法提供准确的坐标_Xamarin_Xamarin.forms - Fatal编程技术网

Xamarin pan手势识别器无法提供准确的坐标

Xamarin pan手势识别器无法提供准确的坐标,xamarin,xamarin.forms,Xamarin,Xamarin.forms,我正在用平移手势识别器做一些测试。设置非常简单,我有一个20x20的长方体视图,由一个相对布局设置。平移手势的处理程序 switch (args.StatusType) { case GestureStatus.Running: box.TranslationX = box.X + args.TotalX; box.TranslationY = box.Y +

我正在用平移手势识别器做一些测试。设置非常简单,我有一个20x20的长方体视图,由一个相对布局设置。平移手势的处理程序

switch (args.StatusType)
            {
                case GestureStatus.Running:
                    box.TranslationX = box.X + args.TotalX;
                    box.TranslationY = box.Y + args.TotalY;
                    break;
                case GestureStatus.Completed:
                    box.TranslationX = 0;
                    box.TranslationY = 0;
                    break;
            }

所以它运行正常,但当我尝试在屏幕上拖动boxview时,它无法正确转换值。当它试图重新绘制方框时,也会产生这种令人讨厌的闪烁效果。有没有更好的方法来做这件事?有什么方法可以消除闪烁吗?

我在Xamarin论坛上找到了一个可以帮助您解决问题的实现()。这是Pan实现,我用我的项目对其进行了测试,发现“闪烁”效果不再存在:

private double startScale, currentScale, xOffset, yOffset, startX, startY;
...
public void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
    switch (e.StatusType)
    {
        case GestureStatus.Started:
            startX = e.TotalX;
            startY = e.TotalY;
            Content.AnchorX = 0;
            Content.AnchorY = 0;
            break;

        case GestureStatus.Running:
            var maxTranslationX = Content.Scale * Content.Width - Content.Width;
            Content.TranslationX = Math.Min(0, Math.Max(-maxTranslationX, xOffset + e.TotalX - startX));

            var maxTranslationY = Content.Scale * Content.Height - Content.Height;
            Content.TranslationY = Math.Min(0, Math.Max(-maxTranslationY, yOffset + e.TotalY - startY));
            break;

        case GestureStatus.Completed:
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;
            break;
    }
}
如果有帮助,请告诉我。

我终于做到了, 假设我想在屏幕上拖动一个boxview,而不存在任何闪烁或协调精度问题, 我为要在屏幕上拖动的视图创建了一个容器,创建了一个 DragEnd事件和特定的EventArgs,当在主窗体中引发此事件时,我从布局的子列表中删除了此容器,并使用EventArgs携带的数据重新添加了新容器:

PanContainer.cs:

public class PanContainer : ContentView
{
    public delegate void DragEndEventHandler(object sender, DragEventArgs e);

    public PanContainer()
    {
        var panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(panGesture);
    }

    public event DragEndEventHandler DragEnd;

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Running:
                Content.TranslationX = e.TotalX;
                Content.TranslationY = e.TotalY;
                break;
            case GestureStatus.Completed:
                OnDragEnd(new DragEventArgs(Content.TranslationX, Content.TranslationY, Width, Height, X, Y));
                break;
            case GestureStatus.Started:
                break;
            case GestureStatus.Canceled:
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    protected virtual void OnDragEnd(DragEventArgs e)
    {
        DragEnd?.Invoke(this, e);
    }
}

public class DragEventArgs : EventArgs
{
    public DragEventArgs(double translationX, double translationY, double w, double h, double x, double y)
    {
        ContentTranslationX = translationX;
        ContentTranslationY = translationY;
        Width = w;
        Height = h;
        X = x;
        Y = y;
    }

    public double ContentTranslationX { get; set; }
    public double ContentTranslationY { get; set; }
    public double Width { get; set; }
    public double Height { get; set; }
    public double X { get; set; }
    public double Y { get; set; }
}
以主要形式:

    private void DraggableOnDragEnd(object sender, DragEventArgs e)
    {
        var bv = new BoxView
        {
            BackgroundColor = Color.Brown
        };
        var pc = new PanContainer
        {
            Padding = 4,
            BackgroundColor = Color.Chartreuse,
            Content = bv
        };
        absoluteLayout.Children.Add(pc,
            new Rectangle(e.X + e.ContentTranslationX, e.Y + e.ContentTranslationY, e.Width, e.Height));
        Task.Run(() =>
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                absoluteLayout.Children.Remove(
                    absoluteLayout.Children.First(x => x.GetType() == typeof(PanContainer)));
                var v = absoluteLayout.Children.First(x => x.GetType() == typeof(PanContainer));
                ((PanContainer) v).DragEnd += DraggableOnDragEnd;
            });
        });
    }


它工作正常,但可能有更好的方法来实现这一点。

好吧,如果是您的长方体具有PangestureRecognitor,闪烁效果只是因为TotalX和TotalY与长方体平移坐标相关

试着改变

box.TranslationX = box.X + args.TotalX;
box.TranslationY = box.Y + args.TotalY;

它应该会起作用


编辑:它只涉及Xamarin Android,它对UWP的工作方式不同。

扩展Julien的解决方案,该解决方案为我(在Android上)解决了这个问题

可以截取并重新计算包含在PanUpdatedEventArgs中的平移手势坐标,以抵消BoxView本身的移动。然后将新的参数传递给另一个处理程序:

    public void Handle_PanUpdated(object sender, Xamarin.Forms.PanUpdatedEventArgs e)
    {
        double TranslationX = box.TranslationX;
        double TranslationY = box.TranslationY;

        double TotalX_Modified = e.TotalX + TranslationX;
        double TotalY_Modified = e.TotalY + TranslationY;

        if (Device.RuntimePlatform == Device.Android)
        { 
            e = new PanUpdatedEventArgs(e.StatusType, e.GestureId, TotalX_Modified, TotalY_Modified);
        }

        Handle_PanUpdate_Modified(sender, e);
    }

您使用的是什么布局?它位于相对布局中。我已经实现了Xamarin()提供的示例,并且出现了相同的行为。我尝试移动的元素在手势过程中闪烁(实际上,它从一个位置快速切换到另一个位置,这导致了这种“闪烁”效果)。感谢您的回复!我现在正在处理它,但是maxTranslation总是返回为0。看起来应该是var maxtransationx=Content.Scale*Screen.Width-Content.Width?您使用屏幕宽度而不是内容宽度的位置?还是我走错了方向?
    public void Handle_PanUpdated(object sender, Xamarin.Forms.PanUpdatedEventArgs e)
    {
        double TranslationX = box.TranslationX;
        double TranslationY = box.TranslationY;

        double TotalX_Modified = e.TotalX + TranslationX;
        double TotalY_Modified = e.TotalY + TranslationY;

        if (Device.RuntimePlatform == Device.Android)
        { 
            e = new PanUpdatedEventArgs(e.StatusType, e.GestureId, TotalX_Modified, TotalY_Modified);
        }

        Handle_PanUpdate_Modified(sender, e);
    }