手势

手势 – 让触控语言成为应用的一部分

我们都对手势很熟悉;许多用户想都不想就知道在 Web 浏览器上平移和通过点击来启动应用。对于我们来说,手势是 Windows 8 交互语言的一种表达形式。通过手势可以获取用户输入,并将输入映射到应用和系统中的自然操作。

手势输入显然是构建在指针之上。许多应用都是使用手势的对象,处理点击、平移和缩放,而与相关的原始指针数据关系不大,只是传递这些数据进行手势检测。

再考虑一下输入平台的层次,每一个级别都支持一组一致的手势,这些手势正好反映了 Windows 8 交互语言。在大多数情况下,您不需要教导用户学习新的概念,他们就会使用您的应用。

图中显示了映射到支持的手势集的 Windows 8 交互语言
图 3:Windows 8 交互语言。注意它如何映射到支持的手势集。

在 Windows 8 中,我们的模型是默认为所有应用提供指针输入,并让其选择要馈送到手势检测的数据集,如何配置该手势检测,以及如何处理输出。这种灵活性让您更容易准确地构建设想的体验。

我们的交互语言注重直接操作的原则,内容应“粘在手指上”。操作可实现这一点。从平台的角度而言,手势是指我们认识并为其提供通知的任何交互。操作就是这些类型的手势之一,与其他手势(如长按)相对应。操作是转换、缩放和旋转变化(线性代数思想的 2D 仿射转换)的组合。对于新“开始”体验的示例,如果您平移,实际上就是一种操作。如果您放下第二根手指饼开始缩放,则也是操作。不仅如此,我们很容易表达从一根手指交互到两根手指的交互,以及平移与缩放之间的转换(或两者相结合)。

HTML 和 XAML 框架为您提供了手势事件,这些事件可以满足大多数需求。如果您需要更多控件,例如额外的配置选项,请使用 Windows 运行时 GestureRecognizer。首先,您可以按照如下进行配置:

C#

 
// C#
public GestureManager(Windows.UI.Xaml.Shapes.Rectangle target, Windows.UI.Xaml.UIElement parent)
{
// Configure gesture recognizer
gestureRecognizer = new Windows.UI.Input.GestureRecognizer();
gestureRecognizer.GestureSettings =
Windows.UI.Input.GestureSettings.Hold |
Windows.UI.Input.GestureSettings.ManipulationRotate |
Windows.UI.Input.GestureSettings.ManipulationRotateInertia |
Windows.UI.Input.GestureSettings.ManipulationScale |
Windows.UI.Input.GestureSettings.ManipulationScaleInertia |
Windows.UI.Input.GestureSettings.ManipulationTranslateInertia |
Windows.UI.Input.GestureSettings.ManipulationTranslateX |
Windows.UI.Input.GestureSettings.ManipulationTranslateY |
Windows.UI.Input.GestureSettings.RightTap |
Windows.UI.Input.GestureSettings.Tap;

// Register event handlers for gestures
gestureRecognizer.ManipulationStarted += OnManipulationStarted;
gestureRecognizer.ManipulationUpdated += OnManipulationUpdated;
gestureRecognizer.ManipulationInertiaStarting += OnManipulationInertiaStarting;
gestureRecognizer.ManipulationCompleted += OnManipulationCompleted;
gestureRecognizer.Holding += OnHolding;
gestureRecognizer.RightTapped += OnRightTapped;
gestureRecognizer.Tapped += OnTapped;
}

JavaScript
// JS
function GestureManager(target, parent) {
var gestureRecognizer = new Windows.UI.Input.GestureRecognizer;

// Configure GestureRecognizer
gestureRecognizer.gestureSettings =
Windows.UI.Input.GestureSettings.hold |
Windows.UI.Input.GestureSettings.manipulationRotate |
Windows.UI.Input.GestureSettings.manipulationRotateInertia |
Windows.UI.Input.GestureSettings.manipulationScale |
Windows.UI.Input.GestureSettings.manipulationScaleInertia |
Windows.UI.Input.GestureSettings.manipulationTranslateInertia |
Windows.UI.Input.GestureSettings.manipulationTranslateX |
Windows.UI.Input.GestureSettings.manipulationTranslateY |
Windows.UI.Input.GestureSettings.rightTap |
Windows.UI.Input.GestureSettings.tap;

// Register event handlers for gestures
gestureRecognizer.addEventListener('manipulationstarted', onManipulationStarted);
gestureRecognizer.addEventListener('manipulationupdated', onManipulationUpdated);
gestureRecognizer.addEventListener('manipulationcompleted', onManipulationCompleted);
gestureRecognizer.addEventListener('manipulationinertiastarting',
onManipulationInertiaStarting);
gestureRecognizer.addEventListener('manipulationinertiacompleted',
onManipulationInertiaCompleted);
gestureRecognizer.addEventListener('holding', onHolding);
gestureRecognizer.addEventListener('tapped', onTapped);
gestureRecognizer.addEventListener('righttapped', onRightTapped);
}

在其核心中,交互应用最感兴趣的是手势。对于大多数应用,流程是声明应用寻找的手势,获取应用所见的指针数据,通过手势检测运行,并处理这些手势。

在此代码段中,可以看到所有指针数据是如何馈送到手势检测的,而不需要检查输入类型或执行任何特定类型的处理:

C#

// C#
void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Make target capture the pointer associated to this event
target.CapturePointer(e.Pointer);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessDownEvent(currentPoint);
}

void OnPointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Route the event to the gesture recognizer
// We pass all intermediate points that might have been coalesced
// in a single PointerMove event.
gestureRecognizer.ProcessMoveEvents(e.GetIntermediatePoints(parent));
}

void OnPointerReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessUpEvent(currentPoint);

// Release pointer capture on the pointer associated to this event
target.ReleasePointerCapture(e.Pointer);
}

void OnPointerWheelChanged(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);
bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
Windows.System.VirtualKeyModifiers.Shift;
bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
Windows.System.VirtualKeyModifiers.Control;

// Route the event to the gesture recognizer
gestureRecognizer.ProcessMouseWheelEvent(currentPoint, shift, ctrl);
}

JavaScript

 
// JS
function onPointerDown(evt) {
// Make target capture the pointer associated to this event
target.msSetPointerCapture(evt.pointerId);

// Route the event to the gesture recognizer
gestureRecognizer.processDownEvent(evt.getCurrentPoint(parent));
}

function onPointerMove(evt) {
// Route the event to the gesture recognizer
// We pass all intermediate points that might have been coalesced
// in a single PointerMove event.
gestureRecognizer.processMoveEvents(evt.getIntermediatePoints(parent));
}

function onPointerUp(evt) {
// Route the event to the gesture recognizer
gestureRecognizer.processUpEvent(evt.getCurrentPoint(parent));
}

function onWheel(evt) {
// Route the event to the gesture recognizer
gestureRecognizer.processMouseWheelEvent(evt.getCurrentPoint(parent), evt.shiftKey,
evt.ctrlKey);
}

对于文档查看应用(如 Word),您主要对平移和缩放感兴趣。可以为这两个操作组件配置手势识别(忽略旋转)。当主视图上的指针数据传入时,应用将其传递给手势识别,然后手势识别返回操作已启动的事件指示,即继续(可能转换为中间状态)或已结束。

编写代码以跨形式和设备扩大应用范围

指针的概念让我们对输入编程有了不同的想法。指针有助于通过减少需要的代码量来实现易于开发性,它可以让您的应用更快地进入应用商店,此外,它还通过让您的应用轻松地定位到多种输入设备而扩大覆盖面。同时,它还让您可以采用更简单的视图来处理输入。我们把其中一种表现形式亲切地称为“代码处理触控,让系统来处理其他任务”。

代码处理触控(或称 CFT)是我们重新思考输入的结果,并且已经成为了我们的主要指导思想。也许更准确的表达是“代码处理指针,轻松获得触控和默认的鼠标以及手写笔行为”,CFT 可让您编写简单的代码来处理统一的指针事件,并且不必担心多余的处理程序来处理所有三种主要指针输入。如果您有特定的输入行为,或者想要除操作系统默认提供的行为之外的行为,也可以实现。

我们在前文中讲述的每种指针事件都证明了实际的 CFT。对于输入类型而言,所有手势示例的指针处理程序都是不可知的。它们通常获取指针数据、设置捕获、执行点击测试或其他状态管理,然后将指针输入传递给手势识别。

C#

// C#
void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Make target capture the pointer associated to this event
target.CapturePointer(e.Pointer);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessDownEvent(currentPoint);
}

JavaScript

// JS
function onPointerDown(evt) {
// Make target capture the pointer associated to this event
target.msSetPointerCapture(evt.pointerId);

// Route the event to the gesture recognizer
gestureRecognizer.processDownEvent(evt.getCurrentPoint(parent));
}

CFT 不仅可以扩大覆盖面和简化开发工作。它还对一致性和信心有直接的影响。例如,如果您为点击配置手势检测,则可以实现通过所有三种输入形式发起的点击。SecondaryTap 的配置将鼠标(单击右键)、触控(长按)和手写笔(长按或筒状按钮点击)的“类似单击右键的手势”映射到统一的事件。

下面是从手势示例中摘录的一个片段,显示了 TapRightTap 手势处理程序:

C#

// C#
void OnTapped(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.TappedEventArgs
args)
{
byte[] rgb = new byte[3];

// Randomly change the color of target
randomGenerator.NextBytes(rgb);
target.Fill = new
Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.ColorHelper.FromArgb(255,
rgb[0], rgb[1], rgb[2]));
}

void OnRightTapped(Windows.UI.Input.GestureRecognizer sender,
Windows.UI.Input.RightTappedEventArgs args)
{
// Restore original values
target.Fill = initialBrush;
InitManipulationTransforms();
}

JavaScript

// JS
function onTapped(evt) {
target.style.backgroundColor = getNextColorFromColor(target.style.backgroundColor);
}

function onRightTapped(evt) {
// Reset target to its initial state (transform, color)
target.style.backgroundColor = target.initialColor;
target.style.msTransform = target.initialTransform;
}

在这些事件处理程序中都没有指针类型的检查。这样让您无需执行额外的工作即可触发来自各种输入类型的相应输入。

结束语

探索平台时,我们希望您轻松地发现您需要的内容,输入经过了精心设计,因此,这种最简单的方式同时也是可以在应用中利用一致 Windows 体验的方式。

输入平台利用一种原则性方法进行设计,目标是简化开发、保持一致性和信心,同时扩大覆盖面。指针和 CFT 之类的概念可以节省您的时间和编写代码的工作量。手势检测可以让您在应用中轻松地使用 Windows 8 交互语言,并为用户提供一致性和信心。平台和框架中的类似概念可以为开发人员提供一致性。CFT 及其在指针中的表现形式和手势 API 让您可以轻松地覆盖设备。

我们对我们在 Windows 8 中付诸的努力感到兴奋不已,希望您能够喜欢!

要了解输入平台的详细信息,请阅读我们的文档、下载示例,或者在论坛上提问。

谢谢!

-- Windows 高级项目经理 Reed Townsend

posted on 2012-09-12 11:37  GIS-MAN  阅读(911)  评论(0编辑  收藏  举报

导航