Megosztás a következőn keresztül:


Lekéréses frissítés forrásmódosítókkal

Ebben a cikkben részletesebben bemutatjuk, hogyan használhatja az InteractionTracker SourceModifier funkcióját, és hogyan szemléltetheti annak használatát egy egyéni lekéréses frissítési vezérlő létrehozásával.

Előfeltételek

Feltételezzük, hogy ismeri az alábbi cikkekben tárgyalt fogalmakat:

Mi az a SourceModifier, és miért hasznosak?

Az InertiaModifiershez hasonlóan a SourceModifiers is finomabb szemcsevezérlést biztosít az InteractionTracker mozgása felett. De ellentétben az InertiaModifiers-szel, amely meghatározza a mozgást, miután az InteractionTracker belépett a tehetetlenségi állapotba, a SourceModifiers a mozgást határozza meg, amíg az InteractionTracker még mindig az interakciós állapotban van. Ezekben az esetekben más élményt szeretne, mint a hagyományos "ujjlenyomat bepiszkolódása".

A klasszikus példa erre a "húzd le a frissítéshez" funkció élménye – amikor a felhasználó lefelé húzza a listát, hogy frissítse a tartalmat, és a lista ugyanazzal a sebességgel mozog, mint az ujja, majd egy bizonyos távolság után megáll, a mozgás hirtelen és gépies érzetet kelt. Természetesebb élmény lenne az ellenállás érzésének bevezetése, miközben a felhasználó aktívan kommunikál a listával. Ez a kis árnyalat segít abban, hogy a teljes végfelhasználói élmény dinamikusabb és vonzóbb legyen a listákkal való interakcióban. A Példa szakaszban részletesebben is bemutatjuk, hogyan lehet ezt felépíteni.

A forrásmódosítóknak két típusa van:

  • DeltaPosition – az aktuális képkocka pozíciója és az ujj előző képkocka pozíciója közötti eltérés az érintéses pásztázás során. Ez a forrásmódosító lehetővé teszi az interakció helyváltoztatásának (delta pozíciójának) módosítását, mielőtt további feldolgozásra küldené. Ez egy Vector3 típusú paraméter, és a fejlesztő módosíthatja a pozíció X, Y vagy Z attribútumait, mielőtt átadaná azt az InteractionTrackernek.
  • DeltaScale – az aktuális keretméret és az érintéses nagyítási interakció során alkalmazott korábbi keretméret közötti eltérés. Ez a forrásmódosító lehetővé teszi az interakció nagyítási szintjének módosítását. Ez egy lebegőpontos típusattribútum, amelyet a fejlesztő módosíthat, mielőtt átadaná azt az InteractionTrackernek.

Ha az InteractionTracker interakciós állapotban van, kiértékeli a hozzá rendelt forrásmódosítókat, és meghatározza, hogy ezek közül melyik érvényes-e. Ez azt jelenti, hogy több forrásmoderálót is létrehozhat és hozzárendelhet egy InteractionTrackerhez. Az egyes elemek meghatározásakor azonban a következőket kell tennie:

  1. Adja meg a feltételt – egy kifejezés, amely meghatározza a feltételes utasítást, amikor ezt az adott forrásmoderálót alkalmazni kell.
  2. A DeltaPosition/DeltaScale definiálása – A forrásmoderáló kifejezés, amely módosítja a DeltaPosition-t vagy a DeltaScale-et a fenti feltétel teljesülésekor.

Example

Most nézzük meg, hogyan készíthet egyéni pull-to-refresh élményt a Source Modifiers segítségével egy meglévő WinUI XAML ListView-vezérlővel. A Canvas-t használjuk majd "Frissítési panelként", amely egy XAML ListView tetejére lesz helyezve, hogy ezt a funkciót megvalósítsuk.

A végfelhasználói élmény érdekében létre szeretnénk hozni az "ellenállás" hatását, mivel a felhasználó aktívan pásztázi a listát (érintéssel), és leállítja a pásztázást, miután a pozíció túllép egy bizonyos ponton.

Lista lekéréses frissítéssel

Ennek a felületnek a munkakódja a GitHubOn található Windows UI Dev Labs adattárban található. Íme a tapasztalat létrehozásának lépésenkénti végigjárása. Az XAML-jelölőkódban a következőket kell megadnia:

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

Mivel a ListView (ThumbnailList) egy XAML-vezérlő, amely már görget, a görgetést a szülőhöz (ContentPanel) kell láncolni, amikor eléri a legfelső elemet, és már nem tud görgetni. (A ContentPanelben a forrásmódosítókat fogja alkalmazni.) Ehhez a ScrollViewer.IsVerticalScrollChainingEnabled értékét igaz értékre kell állítania a ListView jelölőnyelvben. A VisualInteractionSource láncolási módját is mindig értékre kell állítania.

A PointerPressedEvent eseménykezelőt a handledEventsToo paraméterrel igaz értékre kell beállítania. E lehetőség nélkül a PointerPressedEvent nem lesz a ContentPanelhez láncolva, mivel a ListView vezérlő kezeli ezeket az eseményeket, és nem küldi el őket a vizualizációs lánchoz.

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

Most már készen áll arra, hogy ezt az InteractionTrackerrel kösse össze. Először állítsa be az InteractionTrackert, a VisualInteractionSource-t és az InteractionTracker pozícióját használó kifejezést.

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

Ezzel a beállítással a frissítési panel nincs a nézetben az induló pozícióban, így a felhasználó csak a listanézetet látja. Amikor a pásztázás eléri a ContentPanelt, a PointerPressed esemény aktiválódik, ahol utasítja a rendszert, hogy használja az InteractionTrackert a manipulációs élmény elősegítésére.

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

Megjegyzés:

Ha az események láncolására nincs szükség, a PointerPressedEvent kezelő közvetlenül az XAML jelölésben az attribútum (PointerPressed="Window_PointerPressed") használatával adható hozzá.

A következő lépés a forrásmódosítók beállítása. Ennek a viselkedésnek a lekéréséhez két forrásmoderálót fog használni; Ellenállás és stop.

  • Ellenállás – Mozgassa a DeltaPosition.Y-t a sebesség felére, amíg el nem éri a RefreshPanel magasságát.
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;
  • Leállítás – Álljon meg, miután a teljes RefreshPanel a képernyőn van.
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);

Ez a diagram a SourceModifiers beállításának vizualizációját mutatja be.

Pásztázó diagram

A SourceModifiers segítségével a ListView lefelé pásztázásakor és a legfelső elem elérésekor a frissítési panel le lesz húzva a pásztázó tempójának felére, amíg el nem éri a RefreshPanel magasságát, majd leáll.

A teljes mintában egy kulcsframe animációval pörgetnek egy ikont a RefreshPanel vásznon történő interakció közben. Bármilyen tartalmat lehet a helyére használni, vagy az InteractionTracker pozícióját alkalmazva külön vezérelheti az animációt.