Xamarin 表单滑动 Left/Swipe 向右手势

Xamarin Forms Swipe Left/Swipe Right Gestures

首先我想说我是移动开发、Xamarin、C#、.Net 的新手。

我正在使用 Xamarain Forms 创建一个移动应用程序,并且 运行 遇到了我无法使用滑动手势的问题,至少根据我看到的文档是这样。

我找到了这个网站:http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/

这描述了如何为 IOS/Android 添加一些额外的手势以便在表单的上下文中访问。在尝试进行此操作之前,我想看看是否还有其他人在 Xamarin Forms 应用程序中实现了滑动,以及他们是如何实现的。

我的目标是必须有水平堆栈布局。此布局包含 7 个按钮,每个按钮反映当前一周中的一天。在堆栈布局上向左滑动会将按钮的文本更改为上周。向右滑动会将按钮的文本更改为下周。

所以我也在尝试为此使用 MVVM XAML。那么我可以将向左滑动和向右滑动的动作分开吗?我想使用ICommand根据滑动的方向将某个参数传递给一个函数

如有任何此类示例或任何建议,我们将不胜感激。

您可以随时查看 this 简单演示。并按如下方式使用它:

GestureFrame gi = new GestureFrame
        {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            BackgroundColor = Color.FromHex("bf3122"),
        };

        gi.SwipeDown += (s, e) =>
        {
            DisplayAlert("Gesture Info", "Swipe Down Detected", "OK");
            ViewModel.SampleCommand.Execute("Swipe Down Detected");
        };

        gi.SwipeTop += (s, e) =>
        {
            DisplayAlert("Gesture Info", "Swipe Top Detected", "OK");
            ViewModel.SampleCommand.Execute("Swipe Top Detected");
        };

        gi.SwipeLeft += (s, e) =>
        {
            DisplayAlert("Gesture Info", "Swipe Left Detected", "OK");
            ViewModel.SampleCommand.Execute("Swipe Left Detected");
        };

        gi.SwipeRight += (s, e) =>
        {
            DisplayAlert("Gesture Info", "Swipe Right Detected", "OK");
            ViewModel.SampleCommand.Execute("Swipe Right Detected");
        };

        this.Content = gi;

不需要第三方库..不需要付费..只需添加这两个 类 并实现您的滑动监听器

第一步:复制粘贴这两个类

SwipeListener.cs

using System;
using Xamarin.Forms;

namespace SwipeLib
{
public class SwipeListener : PanGestureRecognizer
{
    private ISwipeCallBack mISwipeCallback;
    private double translatedX = 0, translatedY = 0;

    public SwipeListener(View view, ISwipeCallBack iSwipeCallBack)
    {
        mISwipeCallback = iSwipeCallBack;
        var panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += OnPanUpdated;
        view.GestureRecognizers.Add(panGesture);
    }

    void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {

        View Content = (View)sender;

        switch (e.StatusType) {

            case GestureStatus.Running:

                try {
                    translatedX = e.TotalX;
                    translatedY = e.TotalY;
                } catch (Exception err) {
                    System.Diagnostics.Debug.WriteLine("" + err.Message);
                }
                break;

            case GestureStatus.Completed:

                System.Diagnostics.Debug.WriteLine("translatedX : " + translatedX);
                System.Diagnostics.Debug.WriteLine("translatedY : " + translatedY);

                if (translatedX < 0 && Math.Abs(translatedX) > Math.Abs(translatedY)) {
                    mISwipeCallback.onLeftSwipe(Content);
                } else if (translatedX > 0 && translatedX > Math.Abs(translatedY)) {
                    mISwipeCallback.onRightSwipe(Content);
                } else if (translatedY < 0 && Math.Abs(translatedY) > Math.Abs(translatedX)) {
                    mISwipeCallback.onTopSwipe(Content);
                } else if (translatedY > 0 && translatedY > Math.Abs(translatedX)) {
                    mISwipeCallback.onBottomSwipe(Content);
                } else {
                    mISwipeCallback.onNothingSwiped(Content);
                }

                break;

        }
    }

}
}

ISwipeCallBack.cs

using System;
using Xamarin.Forms;
namespace SwipeLib
{  
public interface ISwipeCallBack
{

    void onLeftSwipe(View view);
    void onRightSwipe(View view);
    void onTopSwipe(View view);
    void onBottomSwipe(View view);
    void onNothingSwiped(View view);
}
}

第 2 步:从您的 Xamarin 表单传递视图和接口对象。然后你得到结果

在我的例子中,我传递了标签

 SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);

步骤 3:实现 ISwipeCallBack 接口

public partial class SwipeLibPage : ContentPage, ISwipeCallBack

示例项目 --> https://github.com/rranjithkumar100/Xamarin-Swipe-Library

基于@Ranjith Kumar 的解决方案,我得出了以下结论:

public delegate void SwipedEventHandler(ISwipeListener sender, SwipedEventArgs e);

public class SwipedEventArgs : EventArgs
{
    readonly double _x;
    public double X => _x;

    readonly double _y;
    public double Y => _y;

    readonly View _view;
    public View View => _view;

    public SwipedEventArgs(View view, double x, double y)
    {
        _view = view;
        _x = x;
        _y = y;
    }
}

public interface ISwipeListener
{
    event SwipedEventHandler SwipedDown;

    event SwipedEventHandler SwipedLeft;

    event SwipedEventHandler SwipedNothing;

    event SwipedEventHandler SwipedRight;

    event SwipedEventHandler SwipedUp;

    double TotalX
    {
        get;
    }

    double TotalY
    {
        get;
    }
}

public class SwipeListener : PanGestureRecognizer, ISwipeListener
{
    public event SwipedEventHandler SwipedDown;

    public event SwipedEventHandler SwipedLeft;

    public event SwipedEventHandler SwipedNothing;

    public event SwipedEventHandler SwipedRight;

    public event SwipedEventHandler SwipedUp;

    double _totalX = 0, _totalY = 0;

    public double TotalX => _totalX;

    public double TotalY => _totalY;

    readonly View _view;

    public SwipeListener(View view) : base()
    {
        _view = view;
        _view.GestureRecognizers.Add(this);
        PanUpdated += OnPanUpdated;
    }

    void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        switch (e.StatusType)
        {
            case GestureStatus.Running:
                try
                {
                    _totalX = e.TotalX;
                    _totalY = e.TotalY;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.Message);
                }
                break;

            case GestureStatus.Completed:
                if (_totalX < 0 && Math.Abs(_totalX) > Math.Abs(_totalY))
                {
                    OnSwipedLeft(_totalX, _totalY);
                }
                else if (_totalX > 0 && _totalX > Math.Abs(_totalY))
                {
                    OnSwipedRight(_totalX, _totalY);
                }
                else if (_totalY < 0 && Math.Abs(_totalY) > Math.Abs(_totalX))
                {
                    OnSwipedUp(_totalX, _totalY);
                }
                else if (_totalY > 0 && _totalY > Math.Abs(_totalX))
                {
                    OnSwipedDown(_totalX, _totalY);
                }
                else OnSwipedNothing(_totalX, _totalY);
                break;

        }
    }

    protected virtual void OnSwipedDown(double x, double y)
        => SwipedDown?.Invoke(this, new SwipedEventArgs(_view, x, y));

    protected virtual void OnSwipedLeft(double x, double y)
        => SwipedLeft?.Invoke(this, new SwipedEventArgs(_view, x, y));

    protected virtual void OnSwipedNothing(double x, double y)
        => SwipedNothing?.Invoke(this, new SwipedEventArgs(_view, x, y));

    protected virtual void OnSwipedRight(double x, double y)
        => SwipedRight?.Invoke(this, new SwipedEventArgs(_view, x, y));

    protected virtual void OnSwipedUp(double x, double y)
        => SwipedUp?.Invoke(this, new SwipedEventArgs(_view, x, y));
}

缺点是在执行滑动时你不能做任何事情,只能在之后。

也许这对某人有帮助。

我遇到了一个问题:里面有一个带有滚动视图和网格的 ContentPage。我需要做的就是处理滑动 left/right 手势。 通过 google/Whosebug/github 搜索后,我找到了一个名为 XamarinFormsGestures 的 Nuget 包。这对我帮助很大。所有指令都在link里面。 有我的代码:

Vapolia.Lib.Ui.Gesture.SetSwipeLeftCommand(scrollviewgrid, 
new Command(() => { OnLeftSwipe(); })); // What's going on when left swiped.
Vapolia.Lib.Ui.Gesture.SetSwipeRightCommand(scrollviewgrid, 
new Command(() => { OnRightSwipe(); })); // What's going on when right swiped.

Xamarin.Forms 引入了 SwipeGestureRecognizer :

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
    </BoxView.GestureRecognizers>
</BoxView>

仅供参考

SwipeView 在 Xamarin.Forms 4.4 中可用。

SwipeViewclass还定义了四个事件:

SwipeStarted 在滑动开始时触发。伴随此事件的 SwipeStartedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。

SwipeChanging 在滑动移动时触发。 伴随此事件的 SwipeChangingEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性 和类型为 double 的 Offset 属性。

SwipeEnded 在滑动结束时触发。伴随此事件的 SwipeEndedEventArgs 对象具有类型为 SwipeDirection 的 SwipeDirection 属性。

CloseRequested 在滑动项关闭时触发。 另外,SwipeView定义了一个Close方法,用于关闭滑动项。

有关 Xamarin Forms 一些新功能的更多信息,请访问此 link