InteractionTracker 的自定义操作体验

本文介绍如何使用 InteractionTracker 创建自定义操作体验。

先决条件

我们在此假设你熟悉这些文章中所述的概念:

为什么创建自定义操作体验?

在大多数情况下,利用预生成的操作控件足以创建 UI 体验。 但是,如果想要与常见控件进行区分,该怎么办? 如果想要创建由输入驱动的特定体验或具有传统操作运动不足的 UI,该怎么办? 这是创建自定义体验的位置。 它们使应用开发人员和设计人员能够更具创意 - 让运动体验更生动,能更好的体现品牌和自定义设计语言。 从头开始,你可以访问正确的构建基块集,以完全自定义操作体验 - 从手指在屏幕上和离开屏幕时运动应该如何响应,到对齐点和输入链接。

下面是创建自定义操作体验的一些常见场景示例:

  • 添加自定义轻扫、删除/关闭行为
  • 输入驱动的效果(平移会导致内容模糊)
  • 具有定制操作动作的自定义控件(自定义 ListView、ScrollViewer 等)

Swipe scroller example

Pull to animate example

为什么要使用 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 对象。 下图还概述了何时触发不同事件。

InteractionTracker state machine

使用 VisualInteractionSource

要使 InteractionTracker 由 Input 驱动,需要将 VisualInteractionSource (VIS) 与其连接。 VIS 是使用 CompositionVisual 创建的,可作为补充对象,其用途是定义以下内容:

  1. 将跟踪输入的命中测试区域,并在其中检测到坐标空间手势
  2. 将检测和路由的输入的配置,其中包括:
    • 可检测手势:位置 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 创建自定义操作体验:

  1. 使用 InteractionTracker.Create 或 InteractionTracker.CreateWithOwner 创建 InteractionTracker 对象。
    • (如果使用 CreateWithOwner,请确保实现 IInteractionTrackerOwner 接口。)
  2. 设置新创建的 InteractionTracker 的最小值和最大值位置。
  3. 使用 CompositionVisual 创建 VisualInteractionSource。
    • 确保传入的视觉对象大小为非零。 否则,测试命中的结果将不正确。
  4. 设置 VisualInteractionSource 的属性。
    • VisualInteractionSourceRedirectionMode
    • PositionXSourceMode、PositionYSourceMode、ScaleSourceMode
    • 轨道和链
  5. 使用 InteractionTracker.InteractionSources.Add 将 VisualInteractionSource 添加到 InteractionTracker。
  6. 在检测到触控和笔 输入时设置 TryRedirectForManipulation。
    • 对于 XAML,这通常在 UIElement 的 PointerPressed 事件上完成。
  7. 创建引用 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 的更高级用法,请参阅以下文章: