web-dev-qa-db-fra.com

Xamarin Forms Balayer Gauche/Balayer Droite Gestes

Je voudrais commencer par dire que je suis complètement nouveau dans le développement mobile, Xamarin, C #, .Net.

Je travaille sur la création d'une application mobile à l'aide de Xamarain Forms et je suis confronté au problème de ne pas avoir le geste de glisser disponible, du moins d'après la documentation que j'ai vue. 

J'ai trouvé ce site: http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/

Ceci décrit comment ajouter des gestes supplémentaires pour que IOS/Android soit accessible dans le contexte du formulaire. Avant d’essayer de suivre cette question, je voulais savoir si d’autres personnes avaient implémenté le balayage dans une application Xamarin Forms et comment elles s’y prenaient.

Mes objectifs sont qu'il doit y avoir une disposition de pile horizontale. Cette mise en page contient 7 boutons, chaque bouton reflète un jour de la semaine en cours. Glisser à gauche sur la disposition de la pile changera le texte du bouton à la semaine précédente. Glisser vers la droite changera le texte du bouton à la semaine prochaine.

Donc, j'essaie également d'utiliser MVVM pour cela et XAML. Est-il donc possible pour moi de séparer le glissement gauche et l'action droite? Je souhaite utiliser ICommand pour transmettre un paramètre donné à une fonction en fonction de la direction du balayage.

Des exemples de cela ou des conseils seraient grandement appréciés.

27
Kyle

Xamarin.Forms a introduit SwipeGestureRecognizer:

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

Pas besoin de bibliothèques tierces .. Pas besoin de payer .. Ajoutez simplement ces deux classes et implémentez vos écouteurs 

Etape 1: Copier coller ces deux classes

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

Étape 2: À partir de vos formulaires Xamarin, passez la vue et l'interface obj. Ensuite, vous obtenez le résultat

Dans mon cas je passe l'étiquette 

 SwipeListener swipeListener = new SwipeListener(lbl_swipe, this);

Étape 3: implémentez l'interface ISwipeCallBack 

public partial class SwipeLibPage : ContentPage, ISwipeCallBack

Exemple de projet -> https://github.com/rranjithkumar100/Xamarin-Swipe-Library

26
Ranjith Kumar

Si vous préférez payer pour une bibliothèque tierce (et que vous utilisez Xamarin Forms, c'est donc une bonne possibilité), MR.Gestures prend en charge tous les mouvements tactiles sur toutes les vues Xamarin.Forms. Je l'ai utilisé avec succès et j'en suis vraiment content. Cela coûte 10 € très raisonnable et dispose d'une excellente documentation.

Si vous êtes une des nombreuses personnes déçues que les gestes tactiles ne soient pas pris en charge dans Xamarin Forms, envisagez de voter pour cette suggestion de UserVoice .

11
Joel Anair

Vous pouvez toujours regarder this demo simple. Et utilisez-le comme suit:

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
Tomasz Kowalczyk

Peut-être que cela pourrait aider quelqu'un.

J'ai eu un problème: il y avait un ContentPage avec scrollview et grid. Tout ce que je dois faire est de gérer les gestes de balayage gauche/droite ... Après une recherche dans google/stackoverflow/github, j'ai trouvé un paquet Nuget appelé XamarinFormsGestures . Cela m'a beaucoup aidé. Toutes les instructions sont dans le lien . Voici mon code:

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.

En me basant sur la solution de @Ranjith Kumar, j'ai proposé ce qui suit:

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

L'inconvénient est que vous ne pouvez rien faire tant que le balayage est effectué, mais seulement après.

2
James M

Vous pouvez utiliser le package NuGet "XamarinFormsGesture" de Vapolia (doc disponible ici ). C'est gratuit et facile à utiliser.

Disponible sur iOS et Android, mais cela ne fonctionne que sur des périphériques physiques (pas sur simulateur).