【问题标题】:Zoom out lags on Xamarin.Form implementation缩小 Xamarin.Form 实施的滞后
【发布时间】:2018-12-24 18:04:13
【问题描述】:

我需要在 Xamarin.Form 应用程序中放大/缩小图像。 我的问题是,当我用捏合手势缩小图像时,它开始滞后并在整个显示屏上闪烁。相反,放大效果很好。 我已经遵循了官方指南 (https://docs.microsoft.com/it-it/xamarin/xamarin-forms/app-fundamentals/gestures/pinch) 和任何形式的论坛/社区,但我无法找到有效的答案。 有人可以帮我吗? 我在这里复制/粘贴代码部分。我本地化了我尝试设置 currentScale 变量的错误。

注意:我在类中有其他方法,但它们不管理图像或相关属性,因此我不复制/粘贴它们。

    public partial class ResizeFoto : ContentPage
        {

        double currentScale = 1;
        double startScale = 1;       
        double minScale = 0;
        double maxScale = 2.5;

        private void PinchGestureRecognizer_PinchUpdated(object sender,PinchGestureUpdatedEventArgs e){
                    switch (e.Status)
                    {
                        case GestureStatus.Started:
                            startScale = imgUserFoto.Scale;
                            break;

                        case GestureStatus.Running:

                            // LAS test 4
                            //Input gesture:
                            //Definition: "The distance between the user's digits, divided by the 
                            //last reported distance between the user's digits in the pinch gesture"
                            // --> ZOOM IN = e.Scale > 1
                            // --> ZOOM OUT = e.Scale < 1

                            //ZOOM IN --> works good
                            if (e.Scale > 1)
                            {
                                currentScale += (e.Scale - 1) * startScale;
                                currentScale = Math.Min(currentScale, maxScale);
                                imgUserFoto.Scale = currentScale;
                            }

                            //ZOOM OUT --> not working, bug
                            else if (e.Scale < 1)
                            {
        //HERE MAYBE THE BUG
                                    currentScale = minScale + (e.Scale - 1) * startScale;
       //also tried: currentScale = (e.Scale - 1) * startScale;
                                    currentScale = Math.Max(minScale, currentScale); 
                                    imgUserFoto.Scale = currentScale;
                                }
                            }
                         break; 
                        case GestureStatus.Completed:

                         break;
                     }
        }

}

【问题讨论】:

  • visual-studio 标签适用于与 Visual Studio 应用程序相关的问题,而不是您使用它创建的代码。

标签: c# xamarin xamarin.forms


【解决方案1】:

最近我不得不做类似的事情,我几乎搜索了整个地球,一无所获然后我想出了这个:

using System;
using Xamarin.Forms;
using FFImageLoading.Forms;

 public class ZoomImage : CachedImage
{
    private const double MIN_SCALE = 1;
    private const double MAX_SCALE = 4;
    private const double OVERSHOOT = 0.15;
    private double StartScale, LastScale;
    private double StartX, StartY;

    public ZoomImage()
    {
        var pinch = new PinchGestureRecognizer();
        pinch.PinchUpdated += OnPinchUpdated;
        GestureRecognizers.Add(pinch);

        var pan = new PanGestureRecognizer();
        pan.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(pan);

        var tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
        tap.Tapped += OnTapped;
        GestureRecognizers.Add(tap);

        Scale = MIN_SCALE;
        TranslationX = TranslationY = 0;
        AnchorX = AnchorY = 0;
    }

    protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
    {
        Scale = MIN_SCALE;
        TranslationX = TranslationY = 0;
        AnchorX = AnchorY = 0;
        return base.OnMeasure(widthConstraint, heightConstraint);
    }

    private void OnTapped(object sender, EventArgs e)
    {
        if (Scale > MIN_SCALE)
        {
            this.ScaleTo(MIN_SCALE, 250, Easing.CubicInOut);
            this.TranslateTo(0, 0, 250, Easing.CubicInOut);
        }
        else
        {
            AnchorX = AnchorY = 0.5; //TODO tapped position
            this.ScaleTo(MAX_SCALE, 250, Easing.CubicInOut);
        }
    }

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Started:
                StartX = (1 - AnchorX) * Width;
                StartY = (1 - AnchorY) * Height;
                break;
            case GestureStatus.Running:
                AnchorX = Clamp(1 - (StartX + e.TotalX) / Width, 0, 1);
                AnchorY = Clamp(1 - (StartY + e.TotalY) / Height, 0, 1);
                break;
        }
    }

    private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        switch (e.Status)
        {
            case GestureStatus.Started:
                LastScale = e.Scale;
                StartScale = Scale;
                AnchorX = e.ScaleOrigin.X;
                AnchorY = e.ScaleOrigin.Y;
                break;
            case GestureStatus.Running:
                if (e.Scale < 0 || Math.Abs(LastScale - e.Scale) > (LastScale * 1.3) - LastScale)
                { return; }
                LastScale = e.Scale;
                var current = Scale + (e.Scale - 1) * StartScale;
                Scale = Clamp(current, MIN_SCALE * (1 - OVERSHOOT), MAX_SCALE * (1 + OVERSHOOT));
                break;
            case GestureStatus.Completed:
                if (Scale > MAX_SCALE)
                    this.ScaleTo(MAX_SCALE, 250, Easing.SpringOut);
                else if (Scale < MIN_SCALE)
                    this.ScaleTo(MIN_SCALE, 250, Easing.SpringOut);
                break;
        }
    }

    private T Clamp<T>(T value, T minimum, T maximum) where T: IComparable
    {
        if (value.CompareTo(minimum) < 0)
            return minimum;
        else if (value.CompareTo(maximum) > 0)
            return maximum;
        else
            return value;
    }
}

这是做什么的:

捏缩放、平移和滑动移动以及双击中心缩放和取消缩放

注意:我使用了 FFimageLoading 的 CachedImage,因为我需要缓存数据以防您不打算这样做,将 CachedImage 替换为 Xamarin.Forms.Image

【讨论】:

  • 嗨@G.hakim,首先感谢您的回复! :) 我尝试在我的情况下应用您的代码的 pinchgesture 部分,但不幸的是它不起作用。在手势运行过程中仍然有那些令人讨厌的闪烁窃听效果。 D:在这里你可以找到唯一一个与我们类似的讨论,我可以在网上找到:stackoverflow.com/questions/45554053/…(遗憾的是,这个解决方案对我来说都没有用)
  • 我建议你只使用控件而不是捏代码,因为这会有所帮助
  • “使用控件”是什么意思? :)
  • 使用缩放图像控件代替您现在使用的任何东西,看看它是否有效,因为您面临的问题可能是您拥有的代码有问题,因此可能导致问题
  • 谢谢,你有一些 Xamarin 指南链接或其他我可以研究此功能的东西吗?
猜你喜欢
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多