web-dev-qa-db-ja.com

Xamarin Formsはスワイプ左/スワイプ右ジェスチャーを形成します

私は、モバイル開発、Xamarin、C#、. Netを完全に初めてだと言って、これを序文にしたいと思います。

私はXamarain Formsを使用してモバイルアプリの作成に取り組んでいますが、少なくとも私が見たドキュメントによると、スワイプジェスチャーを使用できないという問題に遭遇しました。

このサイトを見つけました: http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/

これは、IOS/Androidがフォームのコンテキストでアクセスできるように、いくつかの追加のジェスチャーを追加する方法を説明しています。これに従う前に、他の誰かがXamarin Formsアプリでスワイプを実装しているかどうか、そしてそれがどのように進んだかを確認したかったのです。

私の目標は、水平スタックレイアウトが必要であることです。このレイアウトには7つのボタンが含まれ、各ボタンは現在の週の1日を反映しています。スタックレイアウトを左にスワイプすると、ボタンのテキストが前の週に変更されます。右にスワイプすると、ボタンのテキストが次の週に変更されます。

だから、これとXAMLにMVVMを使用しようとしています。だから、左にスワイプするアクションと右にスワイプするアクションを分離することは可能ですか? ICommandを使用して、スワイプの方向に基づいて特定のパラメーターを関数に渡します。

この例やアドバイスは大歓迎です。

29
Kyle

Xamarin.FormsはSwipeGestureRecognizerを導入しました:

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
    </BoxView.GestureRecognizers>
</BoxView>
10
Amir No-Family

サードパーティのライブラリは必要ありません。支払いは不要です。これらの2つのクラスを追加して、スワイプリスナーを実装するだけです。

ステップ1:これら2つのクラスをコピーして貼り付けます

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フォームからビューとインターフェイスobjを渡します。次に、結果を取得します

私の場合、ラベルを渡します

 SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);

ステップ3:ISwipeCallBackインターフェイスを実装する

public partial class SwipeLibPage : ContentPage, ISwipeCallBack

サンプルプロジェクト-> https://github.com/rranjithkumar100/Xamarin-Swipe-Library

26
Ranjith Kumar

サードパーティライブラリの支払いに満足している場合(そしてXamarin Formsを使用しているので、それが可能性が高い)、 MR.Gestures はすべてのXamarin.Formsビューですべてのタッチジェスチャをサポートします。私はそれを成功裏に使用し、本当に満足しています。非常にリーズナブルな10ユーロで、優れたドキュメントがあります。

タッチジェスチャがXamarin Formsでサポートされていないことに失望している多くの人の1人である場合は、 serVoiceでのこの提案 への投票を検討してください。

11
Joel Anair

this simple demoをいつでも見ることができます。そして、次のように使用します。

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;
7

多分それは誰かを助けることができます。

問題がありました:スクロールビューとグリッドを含むContentPageがありました。私がしなければならないことは、スワイプ左/右ジェスチャーを処理することです。 google/stackoverflow/githubを検索すると、 XamarinFormsGestures というNugetパッケージが見つかりました。それはとても助けになりました。すべての指示はリンク内にあります。私のコードがあります:

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.

@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));
}

欠点は、スワイプが実行されている間は何もできないことです。

2
James M

VapoliaのNuGetパッケージ「XamarinFormsGesture」を使用できます(doc available here )。無料で使いやすいです。

IOSおよびAndroidで使用可能ですが、シミュレータではなく物理デバイスでのみ機能します。