Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans cet article, nous allons approfondir l’utilisation d’une fonction SourceModifier d’InteractionTracker et illustrer son utilisation en créant un contrôle personnalisé de tirer pour actualiser.
Prerequisites
Ici, nous partons du principe que vous connaissez les concepts abordés dans ces articles :
- Animations pilotées par les entrées
- Expériences de manipulation personnalisées avec InteractionTracker
- Animations basées sur des relations
Qu’est-ce qu’un SourceModifier et pourquoi sont-ils utiles ?
Comme InertiaModifiers, les SourceModifiers vous donnent un contrôle plus précis sur le mouvement d’un InteractionTracker. Mais contrairement aux InertieModifiers qui définissent le mouvement après l’entrée d’InteractionTracker dans l’inertie, Les SourcesModifiers définissent le mouvement alors qu’InteractionTracker est toujours dans son état d’interaction. Dans ces cas, vous souhaitez une expérience différente de la traditionnelle « coller au doigt ».
Un exemple classique est l’expérience de balayage vers le bas pour rafraîchir : lorsque l'utilisateur tire la liste pour actualiser le contenu et que la liste défile à la même vitesse que le doigt et s’arrête après une certaine distance, le mouvement semblerait brusque et mécanique. Une expérience plus naturelle serait d’introduire une sensation de résistance alors que l’utilisateur interagit activement avec la liste. Cette petite nuance permet de rendre l’expérience globale de l’utilisateur final d’interagir avec une liste plus dynamique et attrayante. Dans la section Exemple, nous examinons en plus de détails comment construire cela.
Il existe 2 types de modificateurs sources :
- DeltaPosition : est le delta entre la position actuelle du frame et la position précédente du doigt pendant l’interaction tactile du panoramique. Ce modificateur source vous permet de modifier la position delta de l’interaction avant de l’envoyer pour un traitement ultérieur. Il s’agit d’un paramètre de type Vector3 et le développeur peut choisir de modifier l’un des attributs X ou Y ou Z de la position avant de le transmettre à InteractionTracker.
- DeltaScale : est le delta entre l’échelle actuelle d’images et l’échelle d’image précédente qui a été appliquée pendant l’interaction de zoom tactile. Ce modificateur source vous permet de modifier le niveau de zoom de l’interaction. Il s’agit d’un attribut de type float que le développeur peut modifier avant de le transmettre à InteractionTracker.
Lorsque InteractionTracker est dans son état d’interaction, il évalue chacun des modificateurs sources qui lui sont affectés et détermine si l’un d’eux s’applique. Cela signifie que vous pouvez créer et affecter plusieurs modificateurs sources à un InteractionTracker. Toutefois, lors de la définition de chacune d’elles, vous devez effectuer les opérations suivantes :
- Définissez la condition : expression qui définit l’instruction conditionnelle lorsque ce modificateur source spécifique doit être appliqué.
- Définissez deltaPosition/DeltaScale : expression de modificateur source qui modifie DeltaPosition ou DeltaScale lorsque la condition définie ci-dessus est remplie.
Exemple
Examinons maintenant comment utiliser des Modificateurs de Source pour créer une expérience de refresh par glissement personnalisée avec un contrôle ListView XAML WinUI existant. Nous allons utiliser un canevas comme « Panneau d’actualisation » qui sera empilé sur un ListView XAML pour générer cette expérience.
Pour l'expérience de l'utilisateur final, nous voulons créer un effet de « résistance » lorsque l'utilisateur effectue activement un panoramique de la liste par toucher et que le mouvement panoramique s'arrête une fois que la position dépasse un certain point.
Le code de travail de cette expérience se trouve dans le dépôt Windows UI Dev Labs sur GitHub. Voici la procédure pas à pas de la création de cette expérience. Dans votre code de balisage XAML, vous disposez des éléments suivants :
<StackPanel Height="500" MaxHeight="500" x:Name="ContentPanel" HorizontalAlignment="Left" VerticalAlignment="Top" >
<Canvas Width="400" Height="100" x:Name="RefreshPanel" >
<Image x:Name="FirstGear" Source="ms-appx:///Assets/Loading.png" Width="20" Height="20" Canvas.Left="200" Canvas.Top="70"/>
</Canvas>
<ListView x:Name="ThumbnailList"
MaxWidth="400"
Height="500"
ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.IsScrollInertiaEnabled="False" ScrollViewer.IsVerticalScrollChainingEnabled="True" >
<ListView.ItemTemplate>
……
</ListView.ItemTemplate>
</ListView>
</StackPanel>
Étant donné que ListView (ThumbnailList) est un contrôle XAML qui fait déjà défiler, vous avez besoin que le défilement soit chaîné à son parent (ContentPanel) lorsqu’il atteint l’élément le plus haut et ne peut plus faire défiler. (ContentPanel est l’emplacement où vous allez appliquer les modificateurs sources.) Pour ce faire, vous devez définir ScrollViewer.IsVerticalScrollChainingEnabled sur true dans le balisage ListView. Vous devez également définir le mode chaînage sur VisualInteractionSource sur Always.
Vous devez définir le gestionnaire PointerPressedEvent avec le paramètre handledEventsToo comme true. Sans cette option, PointerPressedEvent ne sera pas chaîné au ContentPanel, car le contrôle ListView marque ces événements comme gérés et ils ne seront pas envoyés à la chaîne visuelle.
//The PointerPressed handler needs to be added using AddHandler method with the //handledEventsToo boolean set to "true"
//instead of the XAML element's "PointerPressed=Window_PointerPressed",
//because the list view needs to chain PointerPressed handled events as well.
ContentPanel.AddHandler(PointerPressedEvent, new PointerEventHandler( Window_PointerPressed), true);
Maintenant, vous êtes prêt à l’associer à InteractionTracker. Commencez par configurer InteractionTracker, VisualInteractionSource et l’expression qui tireront parti de la position d’InteractionTracker.
// InteractionTracker and VisualInteractionSource setup.
_root = ElementCompositionPreview.GetElementVisual(Root);
_compositor = _root.Compositor;
_tracker = InteractionTracker.Create(_compositor);
_interactionSource = VisualInteractionSource.Create(_root);
_interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;
_interactionSource.PositionYChainingMode = InteractionChainingMode.Always;
_tracker.InteractionSources.Add(_interactionSource);
float refreshPanelHeight = (float)RefreshPanel.ActualHeight;
_tracker.MaxPosition = new Vector3((float)Root.ActualWidth, 0, 0);
_tracker.MinPosition = new Vector3(-(float)Root.ActualWidth, -refreshPanelHeight, 0);
// Use the Tacker's Position (negated) to apply to the Offset of the Image.
// The -{refreshPanelHeight} is to hide the refresh panel
m_positionExpression = _compositor.CreateExpressionAnimation($"-tracker.Position.Y - {refreshPanelHeight} ");
m_positionExpression.SetReferenceParameter("tracker", _tracker);
_contentPanelVisual.StartAnimation("Offset.Y", m_positionExpression);
Avec cette configuration, le panneau d'actualisation est hors de la fenêtre d'affichage dans sa position de départ, et tout ce que l'utilisateur voit est le listView. Lorsque le panoramique atteint le ContentPanel, l'événement PointerPressed est déclenché, et vous demandez alors au système d'utiliser InteractionTracker pour piloter l'expérience de manipulation.
private void Window_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch) {
// Tell the system to use the gestures from this pointer point (if it can).
_interactionSource.TryRedirectForManipulation(e.GetCurrentPoint(null));
}
}
Note
Si le chaînage des événements gérés n’est pas nécessaire, l’ajout du gestionnaire PointerPressedEvent peut être effectué directement via le balisage XAML à l’aide de l’attribut (PointerPressed="Window_PointerPressed").
L’étape suivante consiste à configurer les modificateurs sources. Vous utiliserez 2 modificateurs sources pour obtenir ce comportement ; Résistance et arrêt.
- Résistance : déplacez deltaPosition.Y à moitié la vitesse jusqu’à ce qu’elle atteigne la hauteur du RefreshPanel.
CompositionConditionalValue resistanceModifier = CompositionConditionalValue.Create (_compositor);
ExpressionAnimation resistanceCondition = _compositor.CreateExpressionAnimation(
$"-tracker.Position.Y < {pullToRefreshDistance}");
resistanceCondition.SetReferenceParameter("tracker", _tracker);
ExpressionAnimation resistanceAlternateValue = _compositor.CreateExpressionAnimation(
"source.DeltaPosition.Y / 3");
resistanceAlternateValue.SetReferenceParameter("source", _interactionSource);
resistanceModifier.Condition = resistanceCondition;
resistanceModifier.Value = resistanceAlternateValue;
- Arrêter : arrêtez le déplacement lorsque l’intégralité de RefreshPanel est sur l’écran.
CompositionConditionalValue stoppingModifier = CompositionConditionalValue.Create (_compositor);
ExpressionAnimation stoppingCondition = _compositor.CreateExpressionAnimation(
$"-tracker.Position.Y >= {pullToRefreshDistance}");
stoppingCondition.SetReferenceParameter("tracker", _tracker);
ExpressionAnimation stoppingAlternateValue = _compositor.CreateExpressionAnimation("0");
stoppingModifier.Condition = stoppingCondition;
stoppingModifier.Value = stoppingAlternateValue;
Now add the 2 source modifiers to the InteractionTracker.
List<CompositionConditionalValue> modifierList = new List<CompositionConditionalValue>()
{ resistanceModifier, stoppingModifier };
_interactionSource.ConfigureDeltaPositionYModifiers(modifierList);
Ce diagramme fournit une visualisation de la configuration de SourceModifiers.
Maintenant, avec les SourceModifiers, vous remarquerez que lorsque vous faites défiler le ListView vers le bas et que vous atteignez l'élément le plus haut, le panneau d'actualisation est tiré à la moitié du rythme du défilement jusqu'à atteindre la hauteur du RefreshPanel, puis il cesse de bouger.
Dans l’exemple complet, une animation de trame clé est utilisée pour faire tourner une icône pendant l’interaction dans le canevas RefreshPanel. Tout contenu peut être utilisé à sa place ou utiliser la position d’InteractionTracker pour piloter cette animation séparément.
Windows developer