Aggiungere un riconoscimento movimento di scorrimento rapido

Download Sample Scaricare l'esempio

Il movimento di scorrimento rapido si verifica quando si muove un dito sullo schermo in senso orizzontale o verticale e viene spesso usato per avviare la navigazione nel contenuto. Gli esempi di codice in questo articolo sono tratti dall'esempio Swipe Gesture .

Per fare in modo che un elemento View riconosca un movimento di scorrimento rapido, creare un'istanza di SwipeGestureRecognizer, impostare la proprietà Direction su un valore di enumerazione SwipeDirection (Left, Right, Up o Down), se necessario impostare la proprietà Threshold, gestire l'evento Swiped e aggiungere il nuovo sistema di riconoscimento del movimento alla raccolta GestureRecognizers per la vista. L'esempio di codice seguente visualizza un SwipeGestureRecognizer associato a un elemento BoxView:

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

Questo è il codice C# equivalente:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left };
leftSwipeGesture.Swiped += OnSwiped;

boxView.GestureRecognizers.Add(leftSwipeGesture);

La classe SwipeGestureRecognizer include anche una proprietà Threshold, che si può impostare su un valore uint che rappresenta la distanza di scorrimento minima che si deve raggiungere affinché lo scorrimento rapido venga riconosciuto, in unità indipendenti dal dispositivo. Il valore predefinito di questa proprietà è 100, ovvero tutti gli scorrimenti rapidi inferiori a 100 unità indipendenti dal dispositivo verranno ignorati.

Riconoscimento della direzione di scorrimento

Negli esempi precedenti la proprietà Direction viene impostata un singolo valore dell'enumerazione SwipeDirection. Tuttavia, è anche possibile impostare questa proprietà su più valori dell'enumerazione SwipeDirection, in modo che l'evento Swiped venga attivato in risposta a uno scorrimento rapido in più di una direzione. Esiste comunque un vincolo per cui un singolo elemento SwipeGestureRecognizer è in grado di riconoscere solo gli scorrimenti che avvengono sullo stesso asse. Di conseguenza, gli scorrimenti rapidi che si verificano sull'asse orizzontale possono essere riconosciuti impostando la proprietà Direction su Left e Right:

<SwipeGestureRecognizer Direction="Left,Right" Swiped="OnSwiped"/>

Analogamente, gli scorrimenti rapidi che si verificano sull'asse verticale possono essere riconosciuti impostando la proprietà Direction su Up e Down:

var swipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Up | SwipeDirection.Down };

In alternativa, è possibile creare un elemento SwipeGestureRecognizer per ogni direzione di scorrimento in modo da riconoscere gli scorrimenti in ogni direzione:

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

Questo è il codice C# equivalente:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left };
leftSwipeGesture.Swiped += OnSwiped;
var rightSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Right };
rightSwipeGesture.Swiped += OnSwiped;
var upSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Up };
upSwipeGesture.Swiped += OnSwiped;
var downSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Down };
downSwipeGesture.Swiped += OnSwiped;

boxView.GestureRecognizers.Add(leftSwipeGesture);
boxView.GestureRecognizers.Add(rightSwipeGesture);
boxView.GestureRecognizers.Add(upSwipeGesture);
boxView.GestureRecognizers.Add(downSwipeGesture);

Nota

Negli esempi precedenti lo stesso gestore eventi risponde all'attivazione dell'evento Swiped. Tuttavia, ogni istanza di SwipeGestureRecognizer può usare un diverso gestore eventi se necessario.

Risposta allo scorrimento rapido

Nell'esempio che segue è illustrato un gestore eventi per l'evento Swiped:

void OnSwiped(object sender, SwipedEventArgs e)
{
    switch (e.Direction)
    {
        case SwipeDirection.Left:
            // Handle the swipe
            break;
        case SwipeDirection.Right:
            // Handle the swipe
            break;
        case SwipeDirection.Up:
            // Handle the swipe
            break;
        case SwipeDirection.Down:
            // Handle the swipe
            break;
    }
}

L'elemento SwipedEventArgs può essere esaminato per determinare la direzione di scorrimento, con la logica personalizzata che risponde allo scorrimento rapido come richiesto. La direzione dello scorrimento rapido può essere ottenuta dalla proprietà Direction degli argomenti dell'evento, che sarà impostata su uno dei valori dell'enumerazione SwipeDirection. Inoltre, gli argomenti dell'evento usano anche una proprietà Parameter che verrà impostata sul valore della proprietà CommandParameter, se definito.

Uso dei comandi

La classe SwipeGestureRecognizer include anche le proprietà Command e CommandParameter. Queste proprietà in genere vengono usate nelle applicazioni che usano il modello Model-View-ViewModel (MVVM). La proprietà Command definisce l'elemento ICommand da richiamare quando viene riconosciuto un movimento di scorrimento rapido, con la proprietà CommandParameter che definisce un oggetto da passare a ICommand.. L'esempio di codice seguente illustra come associare la proprietà Command a un elemento ICommand definito nel modello di visualizzazione la cui istanza è impostata come pagina BindingContext:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left, CommandParameter = "Left" };
leftSwipeGesture.SetBinding(SwipeGestureRecognizer.CommandProperty, "SwipeCommand");
boxView.GestureRecognizers.Add(leftSwipeGesture);

Il codice XAML equivalente è:

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Command="{Binding SwipeCommand}" CommandParameter="Left" />
    </BoxView.GestureRecognizers>
</BoxView>

SwipeCommand è una proprietà di tipo ICommand definita nell'istanza del modello di visualizzazione impostato come pagina BindingContext. Quando viene riconosciuto un movimento di scorrimento rapido, viene eseguito il metodo Execute dell'oggetto SwipeCommand. L'argomento per il metodo Execute è il valore della proprietà CommandParameter. Per altre informazioni sui comandi, vedere l'articolo sull'interfaccia di comando.

Creazione di un contenitore dello scorrimento rapido

La classe SwipeContainer, illustrata nell'esempio di codice seguente, è una classe di riconoscimento dello scorrimento rapido generalizzata di cui viene eseguito il wrapping intorno a un oggetto View ai fini del riconoscimento del movimento di scorrimento rapido:

public class SwipeContainer : ContentView
{
    public event EventHandler<SwipedEventArgs> Swipe;

    public SwipeContainer()
    {
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Left));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Right));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Up));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Down));
    }

    SwipeGestureRecognizer GetSwipeGestureRecognizer(SwipeDirection direction)
    {
        var swipe = new SwipeGestureRecognizer { Direction = direction };
        swipe.Swiped += (sender, e) => Swipe?.Invoke(this, e);
        return swipe;
    }
}

La classe SwipeContainer crea oggetti SwipeGestureRecognizer per tutte e quattro le direzioni di scorrimento e associa gestori eventi Swipe. Questi gestori eventi richiamano l'evento Swipe definito da SwipeContainer.

L'esempio di codice XAML seguente illustra il wrapping della classe SwipeContainer intorno a un oggetto BoxView:

<ContentPage ...>
    <StackLayout>
        <local:SwipeContainer Swipe="OnSwiped" ...>
            <BoxView Color="Teal" ... />
        </local:SwipeContainer>
    </StackLayout>
</ContentPage>

L'esempio di codice seguente illustra come SwipeContainer esegue il wrapping di un oggetto BoxView in una pagina C#:

public class SwipeContainerPageCS : ContentPage
{
    public SwipeContainerPageCS()
    {
        var boxView = new BoxView { Color = Color.Teal, ... };
        var swipeContainer = new SwipeContainer { Content = boxView, ... };
        swipeContainer.Swipe += (sender, e) =>
        {
          // Handle the swipe
        };

        Content = new StackLayout
        {
            Children = { swipeContainer }
        };
    }
}

Quando BoxView riceve un movimento di scorrimento rapido, l'evento Swiped viene attivato in SwipeGestureRecognizer. Questa operazione è gestita dalla classe SwipeContainer che attiva il proprio evento Swipe. L'evento Swipe viene gestito nella pagina. L'elemento SwipedEventArgs può quindi essere esaminato per determinare la direzione di scorrimento, con la logica personalizzata che risponde allo scorrimento rapido come richiesto.