【问题标题】:Xamarin add Scale/Rotate to ContentViewXamarin 将缩放/旋转添加到 ContentView
【发布时间】:2020-04-06 09:21:09
【问题描述】:

我有一个问题。 我创建了一个 CustomView,我可以在其中拖放视图,但现在我还想为其添加缩放/旋转功能。现在这里是为移动视图而创建的 OnTouchEvent:

public override bool OnTouchEvent(MotionEvent e)
{
    float x = e.RawX;
    float y = e.RawY;
    var dragView = Element as DraggableView.DraggableView;

    switch (e.Action)
    {
        case MotionEventActions.Down:
            if (dragView.DragMode == DragMode.Touch)
            {
                if (!touchedDown)
                {
                    if (firstTime)
                    {
                        originalX = GetX();
                        originalY = GetY();
                        firstTime = false;
                    }
                    dragView.DragStarted();
                }
                TextMoved = false;
                touchedDown = true;
                stopwatch.Start();
            }
            dX = x - this.GetX();
            dY = y - this.GetY();
            break;
        case MotionEventActions.Move:
            if (touchedDown)
            {
                if (dragView.DragDirection == DragDirectionType.All || dragView.DragDirection == DragDirectionType.Horizontal)
                {
                    SetX(x - dX);
                }

                if (dragView.DragDirection == DragDirectionType.All || dragView.DragDirection == DragDirectionType.Vertical)
                {
                    SetY(y - dY);
                }

                TextMoved = true;
            }
            break;
        case MotionEventActions.Up:
            touchedDown = false;

            if(TextMoved == true)
            {
                dragView.DragEnded();
            }
            else
            {
                MessagingCenter.Send<object, DraggableView.DraggableView>(this, "EditSelectedText", dragView);
            }

            break;
        case MotionEventActions.Cancel:
            touchedDown = false;
            break;
    }
    return base.OnTouchEvent(e);
}

但现在我还需要缩放/旋转功能。 问题是我已经为我的skiasharp 位图创建了它,但这不是skiasharp,所以我不能使用它。

如何在没有skiasharp的情况下在OnTouchEvent中实现这个功能?

【问题讨论】:

  • 您好,您的意思是用手指触摸来实现缩放/旋转到 ContentView 吗?这里有一个关于Scale/Rotate的样本,你可以看看。

标签: c# xamarin xamarin.forms xamarin.android xamarin.ios


【解决方案1】:

有一个关于 ScaleAndRotate 的 xamarin-forms-samples ,但它与 TouchEvent 无关。我找到了使用 PanGestureRecognizer 的方法>PinchGestureRecognizer 来实现它。

创建一个 ScaleAndRotateContainer ContentView,其中包含 PanGestureRecognizerPinchGestureRecognizer

public class ScaleAndRotateContainer : ContentView
{
    double currentScale = 1;
    double startScale = 1;
    double xOffset = 0;
    double yOffset = 0;
    double rotateNum = 1;
    public ScaleAndRotateContainer()
    {
        var pinchGesture = new PinchGestureRecognizer ();
        pinchGesture.PinchUpdated += OnPinchUpdated;
        var panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += PanGesture_PanUpdated;
        GestureRecognizers.Add (pinchGesture);
        GestureRecognizers.Add(panGesture);
    }

    private void PanGesture_PanUpdated(object sender, PanUpdatedEventArgs e)
    {
        rotateNum++;
        this.RotateTo(rotateNum);
        this.AnchorX = 0.5;
        this.AnchorY = 0.5;
    }

    void OnPinchUpdated (object sender, PinchGestureUpdatedEventArgs e)
    {
        if (e.Status == GestureStatus.Started) {
            // Store the current scale factor applied to the wrapped user interface element,
            // and zero the components for the center point of the translate transform.
            startScale = Content.Scale;
            Content.AnchorX = 0;
            Content.AnchorY = 0;
        }
        if (e.Status == GestureStatus.Running) {
            // Calculate the scale factor to be applied.
            currentScale += (e.Scale - 1) * startScale;
            currentScale = Math.Max (1, currentScale);

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the X pixel coordinate.
            double renderedX = Content.X + xOffset;
            double deltaX = renderedX / Width;
            double deltaWidth = Width / (Content.Width * startScale);
            double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the Y pixel coordinate.
            double renderedY = Content.Y + yOffset;
            double deltaY = renderedY / Height;
            double deltaHeight = Height / (Content.Height * startScale);
            double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;

            // Calculate the transformed element pixel coordinates.
            double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
            double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);

            // Apply translation based on the change in origin.
            Content.TranslationX = targetX.Clamp (-Content.Width * (currentScale - 1), 0);
            Content.TranslationY = targetY.Clamp (-Content.Height * (currentScale - 1), 0);

            // Apply scale factor
            Content.Scale = currentScale;
        }
        if (e.Status == GestureStatus.Completed) {
            // Store the translation delta's of the wrapped user interface element.
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;
        }
    }
}

然后在 Xaml 中为 ContentPage 使用它:

xmlns:local="clr-namespace:PinchGesture;assembly=YourNameSpace"

<local:ScaleAndRotateContainer>
    <local:ScaleAndRotateContainer.Content>
        <StackLayout HorizontalOptions="Center" VerticalOptions="Center" >
            <Label Text="Hello Xamarin.Forms!" />
            <Image Source="waterfront.jpg" />
        </StackLayout>
    </local:ScaleAndRotateContainer.Content>
</local:ScaleAndRotateContainer>

效果:

【讨论】:

  • 谢谢,缩放功能工作正常,但我正在寻找两根手指的旋转
  • @Vreesie Okey,如果有两个手指的解决方案将在此处更新。如果有帮助记得在你有时间的时候投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
  • 2011-03-28
  • 2012-03-20
  • 1970-01-01
相关资源
最近更新 更多