本文介绍如何使用 InteractionTracker 创建自定义操作体验。
先决条件
此处,我们假设你熟悉以下文章中讨论的概念:
为什么创建自定义操作体验?
在大多数情况下,利用预生成的操作控件足以创建 UI 体验。 但是,如果想要区分常见控件,该怎么办? 如果想要创建由输入驱动的特定体验或具有传统操作运动不足的 UI,该怎么办? 这是自定义体验产生的关键所在。 它们让应用开发人员和设计人员能够更具创意——实现更符合品牌和自定义设计语言的动态体验。 从零开始,您可以获得合适的构建模块,以完全定制操控体验——从触屏操作与非触屏操作中的运动响应,到对齐点和输入链接。
下面是创建自定义操作体验时的一些常见示例:
- 添加自定义滑动、删除/取消操作
- 输入驱动的效果(平移会导致内容模糊)
- 具有定制操作动作的自定义控件(自定义 ListView、ScrollViewer 等)
为什么使用 InteractionTracker?
在 WinUI 和 Windows 应用 SDK 应用的 Microsoft.UI.Composition.Interactions 命名空间中提供了 InteractionTracker。 InteractionTracker 启用:
- 完全灵活性 – 我们希望你能够自定义和定制操作体验的各个方面:具体而言,在输入期间或响应过程中发生的确切动作。 使用 InteractionTracker 生成自定义操作体验时,你需要的所有旋钮都已准备就绪。
- 平滑性能 – 操作体验的挑战之一是其性能取决于 UI 线程。 当 UI 繁忙时,这可能会对任何操作体验产生负面影响。 InteractionTracker 旨在利用在 60 FPS 的独立线程上运行的新动画引擎,从而产生流畅的动作。
概述:InteractionTracker
创建自定义操作体验时,有两个主要组件与之交互。 我们将首先讨论这些内容:
- InteractionTracker – 维护状态机的核心对象,其属性由活动用户输入或直接更新和动画驱动。 然后,它旨在与 CompositionAnimation 关联以创建自定义操作动作。
- VisualInteractionSource – 一个补充对象,用于定义何时和在哪些条件下将输入发送到 InteractionTracker。 它定义用于 Hit-testing 的 CompositionVisual 以及其他输入配置属性。
作为状态机,InteractionTracker 的属性可以由以下任一项驱动:
- 直接用户交互 – 最终用户直接在 VisualInteractionSource 命中测试区域中操作
- 惯性 - 从编程速度或用户手势,InteractionTracker 的属性在惯性曲线下进行动画处理
- CustomAnimation – 直接面向 InteractionTracker 属性的自定义动画
InteractionTracker 状态机
如前所述,InteractionTracker 是一个状态机,其中包含 4 种状态 ,每个状态都可以转换为其他四种状态中的任何一种。 (有关 InteractionTracker 在这些状态之间转换方式的详细信息,请参阅 InteractionTracker 类文档。
| 州 | 说明 |
|---|---|
| 空闲 | 无活动、驱动输入或动画 |
| 交互 | 检测到活动用户输入 |
| 惯性 | 由活动输入或编程速度生成的活动运动 |
| 自定义动画 | 由自定义动画生成的活动动作 |
在每种情况下,当 InteractionTracker 的状态发生变化时,都会生成一个事件(或回调),您可以侦听。 若要侦听这些事件,它们必须实现 IInteractionTrackerOwner 接口,并使用 CreateWithOwner 方法创建其 InteractionTracker 对象。 下图概述了何时触发不同事件。
使用 VisualInteractionSource
要使 InteractionTracker 由 Input 驱动,需要将 VisualInteractionSource (VIS) 连接到它。 VIS 是使用 CompositionVisual 定义的补充对象创建的:
- 将跟踪输入的命中测试区域,并在其中检测到坐标空间手势
- 将检测和路由的输入配置包括以下几个:
- 可检测手势:位置 X 和 Y(水平和垂直平移)、缩放(收缩)
- 惯性
- Rails 和 链接
- 重定向模式:自动将输入数据重定向到 InteractionTracker
注释
由于 VisualInteractionSource 是根据 Visual 对象的命中测试位置和坐标空间创建的,建议您不要使用会处于运动状态或改变位置的 Visual 对象。
注释
如果有多个命中测试区域,则可以将多个 VisualInteractionSource 实例与同一 InteractionTracker 一起使用。 但是,最常见的情况是只使用一个 VIS。
VisualInteractionSource 还负责管理来自不同形式(触摸、PTP、Pen)的输入数据何时路由到 InteractionTracker。 此行为由 ManipulationRedirectionMode 属性定义。 默认情况下,所有指针输入都发送到 UI 线程,精度触摸板输入将转到 VisualInteractionSource 和 InteractionTracker。
因此,如果要让 Touch 和 Pen(Creators Update)通过 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,请引用跟踪器的位置(或 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 创建自定义操作体验:
- 使用 InteractionTracker.Create 或 InteractionTracker.CreateWithOwner 创建 InteractionTracker 对象。
- (如果使用 CreateWithOwner,请确保实现 IInteractionTrackerOwner 接口。
- 设置新创建的 InteractionTracker 的最小值和最大值位置。
- 使用 CompositionVisual 创建 VisualInteractionSource。
- 确保传入的视觉对象大小为非零。 否则,将无法进行正确的命中检测。
- 设置 VisualInteractionSource 的属性。
- VisualInteractionSourceRedirectionMode
- PositionXSource模式、PositionYSource模式、ScaleSource模式
- Rails 和 链接
- 使用 InteractionTracker.InteractionSources.Add 将 VisualInteractionSource 添加到 InteractionTracker。
- 在检测到 Touch 和 Pen 输入时设置 TryRedirectForManipulation。
- 对于 XAML,这通常在 UIElement 的 PointerPressed 事件上完成。
- 创建一个引用 InteractionTracker 位置的 ExpressionAnimation,并将其应用于 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 的更高级用法,请参阅以下文章: