Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel gaan we dieper in op het gebruik van de SourceModifier-functie van InteractionTracker en laten we het gebruik ervan zien door een aangepast pull-to-refresh-besturingselement te maken.
Vereiste voorwaarden
Hier gaan we ervan uit dat u bekend bent met de concepten die in deze artikelen worden besproken:
- Invoergestuurde animaties
- Aangepaste manipulatie-ervaringen met InteractionTracker
- Op relaties gebaseerde animaties
Wat is een SourceModifier en waarom zijn ze nuttig?
Net als InertiaModifiers geven SourceModifiers u een nauwkeurigere controle over de beweging van een InteractionTracker. Maar in tegenstelling tot InertiaModifiers die de beweging definiëren nadat InteractionTracker inertia binnenkomt, definiëren SourceModifiers de beweging terwijl InteractionTracker nog steeds de interactiestatus heeft. In dergelijke gevallen wilt u een andere ervaring dan de traditionele "stick to the finger".
Een klassiek voorbeeld hiervan is de pull-to-refresh-ervaring: wanneer de gebruiker de lijst trekt om de inhoud te verversen en de lijst meebeweegt met dezelfde snelheid als de vinger en stopt nadat een bepaalde afstand is afgelegd, zou de beweging abrupt en mechanisch aanvoelen. Een meer natuurlijke ervaring zou zijn om een gevoel van weerstand te introduceren terwijl de gebruiker actief communiceert met de lijst. Deze kleine nuance helpt de algehele gebruikerservaring van interactie met een lijst dynamischer en aantrekkelijker te maken. In de sectie Voorbeeld gaan we dieper in op het bouwen hiervan.
Er zijn twee typen bronaanpassingen:
- DeltaPosition – is de delta tussen de huidige framepositie en de vorige framepositie van de vinger tijdens de interactie met de aanraakpan. Met deze bronwijziging kunt u de deltapositie van de interactie wijzigen voordat u deze verzendt voor verdere verwerking. Dit is een Vector3-typeparameter en de ontwikkelaar kan ervoor kiezen om de X- of Y- of Z-kenmerken van de positie te wijzigen voordat deze wordt doorgegeven aan de InteractionTracker.
- DeltaScale: is de delta tussen de huidige frameschaal en de vorige frameschaal die is toegepast tijdens de interactie met het zoomen met aanraakschermen. Met deze bronwijziging kunt u het zoomniveau van de interactie wijzigen. Dit is een float-typekenmerk dat de ontwikkelaar kan wijzigen voordat deze wordt doorgegeven aan de InteractionTracker.
Wanneer InteractionTracker de interactiestatus heeft, evalueert deze elk van de bronmodifiers die eraan zijn toegewezen en bepaalt of een van deze van toepassing is. Dit betekent dat u meerdere bronmodifiers kunt maken en toewijzen aan een InteractionTracker. Maar wanneer u elk definieert, moet u het volgende doen:
- Definieer de voorwaarde: een expressie die de voorwaardelijke instructie definieert wanneer deze specifieke bronaanpassing moet worden toegepast.
- Definieer de DeltaPosition/DeltaScale: de bronaanpassingsexpressie die de DeltaPosition of DeltaScale wijzigt wanneer aan de bovenstaande gedefinieerde voorwaarde wordt voldaan.
Voorbeeld
Laten we nu eens kijken hoe u bronaanpassingen kunt gebruiken om een aangepaste pull-to-refresh-ervaring te maken met een bestaand WinUI XAML ListView-besturingselement. We zullen een Canvas gebruiken als het "Vernieuwingspaneel", dat bovenop een XAML ListView wordt geplaatst om deze ervaring te creëren.
Voor de ervaring van de eindgebruiker willen we het effect van 'weerstand' creëren omdat de gebruiker de lijst actief aan het pannen is (met aanraking) en stoppen met pannen nadat de positie een bepaald punt overschrijdt.
De werkcode voor deze ervaring vindt u in de windows UI Dev Labs-opslagplaats op GitHub. Hier volgt de stapsgewijze procedure voor het bouwen van die ervaring. In uw XAML-markeringscode hebt u het volgende:
<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>
Omdat ListView (ThumbnailList) een XAML-besturingselement is dat al schuift, moet u het schuiven aan het bovenliggende item (ContentPanel) koppelen wanneer het het bovenste item bereikt en niet meer kan schuiven. (ContentPanel is waar u de bronaanpassingen toepast.) Hiervoor moet u ScrollViewer.IsVerticalScrollChainingEnabled instellen op true in de ListView-opmaak. U moet ook de ketenmodus op VisualInteractionSource instellen op Always.
U moet de PointerPressedEvent-handler instellen met de parameter handledEventsToo als true. Zonder deze optie wordt de PointerPressed-gebeurtenis niet doorgestuurd naar de ContentPanel, omdat het ListView-besturingselement deze gebeurtenissen markeert als afgehandeld en ze daardoor niet door de visuele keten heen worden verzonden.
//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);
Nu bent u klaar om dit te koppelen aan InteractionTracker. Begin met het instellen van InteractionTracker, VisualInteractionSource en de expressie die de positie van InteractionTracker benutten.
// 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);
Met deze configuratie is het vernieuwingsvenster buiten de viewport in de beginpositie en alle gebruikers zien de listView wanneer de panning de ContentPanel bereikt, wordt de gebeurtenis PointerPressed geactiveerd, waar u het systeem vraagt om InteractionTracker te gebruiken om de manipulatie-ervaring te stimuleren.
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));
}
}
Opmerking
Als het koppelen van afgehandelde gebeurtenissen niet nodig is, kunt u pointerPressedEvent-handler rechtstreeks via XAML-markeringen toevoegen met behulp van het kenmerk (PointerPressed="Window_PointerPressed").
De volgende stap bestaat uit het instellen van de bronaanpassingen. U gebruikt twee bronaanpassingen om dit gedrag te verkrijgen; Weerstand en Stop.
- Weerstand – Verplaats de DeltaPosition.Y met de helft van de snelheid totdat het de hoogte van het RefreshPanel bereikt.
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;
- Stop – Stop met bewegen zodra het volledige RefreshPanel op het scherm staat.
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);
Dit diagram geeft een visualisatie van de installatie van SourceModifiers.
Nu, met de SourceModifiers, zult u merken dat wanneer u de ListView omlaag schuift en het bovenste item bereikt, het vernieuwingspaneel naar beneden wordt getrokken met de helft van de snelheid van het schuiven, totdat de hoogte van het vernieuwingspaneel wordt bereikt en het dan stopt met bewegen.
In het volledige voorbeeld wordt een keyframeanimatie gebruikt om een pictogram te draaien tijdens interactie in het Canvas RefreshPanel. Elke inhoud kan op zijn plaats worden gebruikt of de positie van InteractionTracker gebruiken om die animatie afzonderlijk aan te sturen.
Windows developer