通过


使用 InteractionTracker 的自定义操作体验

本文介绍如何使用 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 对象。 下图概述了何时触发不同事件。

InteractionTracker 状态机

使用 VisualInteractionSource

要使 InteractionTracker 由 Input 驱动,需要将 VisualInteractionSource (VIS) 连接到它。 VIS 是使用 CompositionVisual 定义的补充对象创建的:

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

  1. 使用 InteractionTracker.Create 或 InteractionTracker.CreateWithOwner 创建 InteractionTracker 对象。
    • (如果使用 CreateWithOwner,请确保实现 IInteractionTrackerOwner 接口。
  2. 设置新创建的 InteractionTracker 的最小值和最大值位置。
  3. 使用 CompositionVisual 创建 VisualInteractionSource。
    • 确保传入的视觉对象大小为非零。 否则,将无法进行正确的命中检测。
  4. 设置 VisualInteractionSource 的属性。
    • VisualInteractionSourceRedirectionMode
    • PositionXSource模式、PositionYSource模式、ScaleSource模式
    • Rails 和 链接
  5. 使用 InteractionTracker.InteractionSources.Add 将 VisualInteractionSource 添加到 InteractionTracker。
  6. 在检测到 Touch 和 Pen 输入时设置 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 的更高级用法,请参阅以下文章: