InteractionTracker 的自定义操作体验
本文介绍如何使用 InteractionTracker 创建自定义操作体验。
先决条件
我们在此假设你熟悉这些文章中所述的概念:
为什么创建自定义操作体验?
在大多数情况下,利用预生成的操作控件足以创建 UI 体验。 但是,如果想要与常见控件进行区分,该怎么办? 如果想要创建由输入驱动的特定体验或具有传统操作运动不足的 UI,该怎么办? 这是创建自定义体验的位置。 它们使应用开发人员和设计人员能够更具创意 - 让运动体验更生动,能更好的体现品牌和自定义设计语言。 从头开始,你可以访问正确的构建基块集,以完全自定义操作体验 - 从手指在屏幕上和离开屏幕时运动应该如何响应,到对齐点和输入链接。
下面是创建自定义操作体验的一些常见场景示例:
- 添加自定义轻扫、删除/关闭行为
- 输入驱动的效果(平移会导致内容模糊)
- 具有定制操作动作的自定义控件(自定义 ListView、ScrollViewer 等)
为什么要使用 InteractionTracker?
10586 SDK 版本的 Windows.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 类文档。)
状态 | 说明 |
---|---|
闲置 | 无活动、驱动输入或动画 |
正在交互 | 检测到活动用户输入 |
惯性 | 由活动输入或编程速度生成的活动运动 |
CustomAnimation | 由自定义动画生成的活动动作 |
在 InteractionTracker 的状态发生更改的每种情况下,都会生成可以侦听的事件(或回调)。 若要侦听这些事件,它们必须实现 IInteractionTrackerOwner 接口,并使用 CreateWithOwner 方法创建其 InteractionTracker 对象。 下图还概述了何时触发不同事件。
使用 VisualInteractionSource
要使 InteractionTracker 由 Input 驱动,需要将 VisualInteractionSource (VIS) 与其连接。 VIS 是使用 CompositionVisual 创建的,可作为补充对象,其用途是定义以下内容:
- 将跟踪输入的命中测试区域,并在其中检测到坐标空间手势
- 将检测和路由的输入的配置,其中包括:
- 可检测手势:位置 X 和 Y(水平和垂直平移)、缩放(收缩)
- 惯性
- 轨道和链
- 重定向模式:自动将输入数据重定向到 InteractionTracker
注意
由于 VisualInteractionSource 是基于视觉对象的命中测试位置和坐标空间创建的,因此建议不要使用将处于运动状态或不断更改位置的视觉对象。
注意
如果有多个命中测试区域,则可以将多个 VisualInteractionSource 实例与同一 InteractionTracker 一起使用。 但是,最常见的情况是只使用一个 VIS。
VisualInteractionSource 还负责管理何时将来自不同形式(触控、PTP、笔)的输入数据路由到 InteractionTracker。 此行为由 ManipulationRedirectionMode 属性定义。 默认情况下,所有指针输入都发送到 UI 线程,精度触摸板输入将转到 VisualInteractionSource 和 InteractionTracker。
因此,如果要让触控和笔(创意者更新)通过 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 创建自定义操作体验:
- 使用 InteractionTracker.Create 或 InteractionTracker.CreateWithOwner 创建 InteractionTracker 对象。
- (如果使用 CreateWithOwner,请确保实现 IInteractionTrackerOwner 接口。)
- 设置新创建的 InteractionTracker 的最小值和最大值位置。
- 使用 CompositionVisual 创建 VisualInteractionSource。
- 确保传入的视觉对象大小为非零。 否则,测试命中的结果将不正确。
- 设置 VisualInteractionSource 的属性。
- VisualInteractionSourceRedirectionMode
- PositionXSourceMode、PositionYSourceMode、ScaleSourceMode
- 轨道和链
- 使用 InteractionTracker.InteractionSources.Add 将 VisualInteractionSource 添加到 InteractionTracker。
- 在检测到触控和笔 输入时设置 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 的更高级用法,请参阅以下文章: