本文將展示如何使用 InteractionTracker 來創造自訂的操控體驗。
先決條件
在這裡,我們假設你已經熟悉這些文章中討論的概念:
為什麼要創造自訂操控體驗?
大多數情況下,利用預設的操作控制即可創造出使用者介面體驗。 但如果你想與常見控制項區分呢? 如果你想創造一個由輸入驅動的特定體驗,或是設計一個傳統操作動作不夠用的使用者介面怎麼辦? 這就是打造客製化體驗的由來。 它們讓應用程式開發者和設計師更具創意——呈現更能展現品牌形象與客製化設計語言的動態體驗。 從零開始,你就能使用正確的組件,完全自訂操控體驗——從手指在螢幕上或螢幕外的動作反應,到點擊點和輸入連鎖反應。
以下是一些常見的自訂操作體驗範例:
- 新增自訂滑動和刪除/駁回行為
- 輸入驅動效果(平移導致內容模糊)
- 自訂控制項搭配客製化操作動作(自訂清單檢視器、ScrollViewer 等)
為什麼要使用 InteractionTracker?
InteractionTracker 可在 Microsoft.UI.Composition.Interactions 命名空間中取得,適用於 WinUI 和 Windows App SDK 應用程式。 InteractionTracker 能啟用:
- 完全彈性 ——我們希望您能自訂並量身打造操控體驗的每一個面向;具體來說,是指在輸入過程中或回應輸入時所發生的精確動作。 用 InteractionTracker 打造自訂操作體驗時,你需要的所有旋鈕都隨手可得。
- 流暢的效能 ——操作體驗的一大挑戰是其效能依賴於使用者介面執行緒。 當使用者介面忙碌時,這會對任何操作體驗產生負面影響。 InteractionTracker 是為了利用新的動畫引擎而打造,該引擎以獨立執行緒以 60 FPS 運作,實現流暢的動作。
概述:InteractionTracker
在創造自訂操控體驗時,你會接觸到兩個主要的元件。 我們先來討論這些:
- InteractionTracker — 維護狀態機的核心物件,其屬性由主動使用者輸入或直接更新與動畫驅動。 它旨在與 CompositionAnimation 綁定,以建立自訂的操作動作。
- VisualInteractionSource — 一個補碼物件,定義輸入何時及在何種條件下傳送至 InteractionTracker。 它定義了用於碰撞測試的 CompositionVisual,以及其他輸入配置屬性。
作為狀態機,InteractionTracker 的特性可由以下任一因素驅動:
- 直接使用者互動——最終使用者直接在 VisualInteractionSource 的命中測試區域內進行操作
- 慣性——無論是程式速度還是使用者手勢,InteractionTracker 的特性會在慣性曲線下動態
- CustomAnimation – 直接針對 InteractionTracker 屬性的自訂動畫
互動追蹤器狀態機
如前所述,InteractionTracker 是一個擁有 4 種狀態的狀態機,每個狀態都可以轉換到其他四個狀態中的任一。 (關於 InteractionTracker 如何在這些狀態間轉換的更多資訊,請參閱 InteractionTracker 類別文件。)
| State | 說明 |
|---|---|
| 閒置 | 沒有主動的控制輸入或動畫 |
| 互動 | 偵測到主動使用者輸入 |
| 慣性 | 由主動輸入或程式速度所產生的主動運動 |
| 自訂動畫 | 自訂動畫產生的主動動作 |
每當 InteractionTracker 狀態改變時,都會產生一個事件(或回調),你可以監聽。 為了讓你能監聽這些事件,他們必須實作 IInteractionTrackerOwner 介面,並使用 CreateWithOwner 方法建立他們的 InteractionTracker 物件。 下圖也說明了不同事件何時會被觸發。
使用視覺互動源 (VisualInteractionSource)
要讓 InteractionTracker 由 Input 驅動,你需要連接到 VisualInteractionSource(VIS)。 VIS 以補集物件形式使用 CompositionVisual 來定義:
- 輸入的命中測試區域會被追蹤,而座標空間中會偵測手勢。
- 會被偵測並路由的輸入配置包括:
- 可偵測的手勢:位置 X 與 Y(水平與垂直平移)、縮放(捏合)
- 慣性
- 鐵軌與鏈條
- 重定向模式:哪些輸入資料會自動導向到 InteractionTracker
備註
由於 VisualInteractionSource 是根據視覺物件的點擊測試位置和座標空間建立的,建議不要使用會移動或改變位置的視覺物件。
備註
如果有多個命中測試區域,你可以用多個 VisualInteractionSource 實例搭配同一個 InteractionTracker。 然而,最常見的情況是只使用一個 VIS。
VisualInteractionSource 也負責管理不同模式(觸控、PTP、筆)輸入資料何時會被路由到 InteractionTracker。 此行為由 ManipulationRedirectionMode 屬性定義。 預設情況下,所有指標輸入都會送到 UI 執行緒,而 Precision 觸控板輸入則會送到 VisualInteractionSource 和 InteractionTracker。
因此,如果你想讓 Touch 和 Pen(創作者更新)透過 VisualInteractionSource 和 InteractionTracker 來驅動操作,你必須呼叫 VisualInteractionSource.TryRedirectForManipulation 方法。 以下一段來自 XAML 應用程式的短片段中,當 UIElement 網格頂端發生觸控事件時,會呼叫此方法:
private void root_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
{
_source.TryRedirectForManipulation(e.GetCurrentPoint(root));
}
}
與 ExpressionAnimations 的合作
當使用 InteractionTracker 來驅動操作體驗時,你主要會與 Scale 和 Position 屬性互動。 與其他 CompositionObject 屬性一樣,這些屬性可以同時是目標,也可以是 CompositionAnimation 中被參考的屬性,最常見的是 ExpressionAnimations。
要在表達式中使用 InteractionTracker,請引用追蹤器的 Position(或 Scale)屬性,如以下範例所示。 當 InteractionTracker 的特性因上述條件而被修改時,表達式的輸出也會隨之改變。
// With Strings
var opacityExp = _compositor.CreateExpressionAnimation("-tracker.Position");
opacityExp.SetReferenceParameter("tracker", _tracker);
// With ExpressionBuilder
var opacityExp = -_tracker.GetReference().Position;
備註
當參考 InteractionTracker 在表達式中的位置時,必須讓該表達式的值被抵消,才能朝正確方向移動。 這是因為 InteractionTracker 從原點的運動軌跡可以在圖表上呈現,使你能以「現實世界」的座標(例如距離原點的距離)來思考其進展。
開始
要開始使用 InteractionTracker 來建立自訂的操作體驗:
- 使用 InteractionTracker.Create 或 InteractionTracker.CreateWithOwner 建立你的 InteractionTracker 物件。
- (如果你使用 CreateWithOwner,務必實作 IInteractionTrackerOwner 介面。)
- 設定你新建立的互動追蹤器的最小與最大位置。
- 用 CompositionVisuals 建立你的 VisualInteractionSource。
- 確保您提供的圖像具有非零大小。 否則,它就無法正確進行命中測試。
- 設定 VisualInteractionSource 的屬性。
- 視覺互動來源重定向模式
- PositionXSourceMode, PositionYSourceMode, ScaleSourceMode
- 鐵軌與鏈條
- 使用 InteractionTracker.InteractionSources.Add 將 VisualInteractionSource 加入 InteractionTracker。
- 當偵測到觸控和筆輸入時,設定"TryRedirectForManipulation"。
- 對於 XAML,這通常在 UIElement 的 PointerPressed 事件中完成。
- 建立一個 ExpressionAnimation,參考 InteractionTracker 的位置並鎖定 CompositionObject 的屬性。
以下是一段簡短的代碼片段,顯示 #1 – 5 的運作情況:
private void InteractionTrackerSetup(Compositor compositor, Visual hitTestRoot)
{
// #1 Create InteractionTracker object
var tracker = InteractionTracker.Create(compositor);
// #2 Set Min and Max positions
tracker.MinPosition = new Vector3(-1000f);
tracker.MaxPosition = new Vector3(1000f);
// #3 Setup the VisualInteractionSource
var source = VisualInteractionSource.Create(hitTestRoot);
// #4 Set the properties for the VisualInteractionSource
source.ManipulationRedirectionMode =
VisualInteractionSourceRedirectionMode.CapableTouchpadOnly;
source.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia;
source.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;
// #5 Add the VisualInteractionSource to InteractionTracker
tracker.InteractionSources.Add(source);
}
欲了解 InteractionTracker 的更進階用法,請參閱以下條目: