跟踪触摸和指针移动

跟踪触摸和指针移动

试用 Compose 方式

Jetpack Compose 是推荐在 Android 设备上使用的界面工具包。了解如何在 Compose 中使用触控和输入功能。

手势 →

本课介绍了如何跟踪触摸事件中的移动操作。

一种新的

onTouchEvent()

触发

ACTION_MOVE事件

只要当前触摸接触位置、压力或大小发生变化。如

检测常用手势中的说明,所有

这些事件都会记录在

MotionEvent 参数(属于

onTouchEvent()。

因为基于手指的触摸并不总是最精确的互动形式,

触摸事件的检测通常更基于移动,而非简单接触。

帮助应用区分基于移动的手势(例如滑动)和

非移动手势(例如点按一次),Android 包含

Touch slop。Touch slop 是指用户可以触摸的距离(以像素为单位)

在手势被解释为基于移动的手势之前四处移动。有关

请参阅管理

ViewGroup。

您可以通过多种方式跟踪手势的移动情况,具体取决于

应用的需求示例如下:

指针的起始位置和结束位置,例如在屏幕上移动某个对象

将对象从 A 点指向 B 点。

指针的行进方向,由 X 和 Y 确定

坐标。

历史事件。可通过调用

MotionEvent 种方式

getHistorySize()。

然后,您可以获取每个对象的位置、大小、时间和压力

使用动作事件的

getHistorical

方法。当呈现用户手指的轨迹时,历史记录会非常有用,

和触摸绘图一样如需了解详情,请参阅 MotionEvent 参考文档。

指针在触摸屏上移动时的速度。

请参阅以下相关资源:

输入事件概览

传感器概览

将自定义视图设为互动式

跟踪速度

您可以执行基于距离或方向的移动手势

指针移动不过,速度通常是跟踪

或决定手势是否发生。为了让

速度计算变得更简单,Android 提供了

VelocityTracker 类。

VelocityTracker 可帮助您跟踪触摸事件的速度。有用

表示速度是手势标准的一部分的手势,例如

快速滑动

以下示例说明了

VelocityTracker API:

Kotlin

private const val DEBUG_TAG = "Velocity"

class MainActivity : Activity() {

private var mVelocityTracker: VelocityTracker? = null

override fun onTouchEvent(event: MotionEvent): Boolean {

when (event.actionMasked) {

MotionEvent.ACTION_DOWN -> {

// Reset the velocity tracker back to its initial state.

mVelocityTracker?.clear()

// If necessary, retrieve a new VelocityTracker object to watch

// the velocity of a motion.

mVelocityTracker = mVelocityTracker ?: VelocityTracker.obtain()

// Add a user's movement to the tracker.

mVelocityTracker?.addMovement(event)

}

MotionEvent.ACTION_MOVE -> {

mVelocityTracker?.apply {

val pointerId: Int = event.getPointerId(event.actionIndex)

addMovement(event)

// When you want to determine the velocity, call

// computeCurrentVelocity(). Then, call getXVelocity() and

// getYVelocity() to retrieve the velocity for each pointer

// ID.

computeCurrentVelocity(1000)

// Log velocity of pixels per second. It's best practice to

// use VelocityTrackerCompat where possible.

Log.d("", "X velocity: ${getXVelocity(pointerId)}")

Log.d("", "Y velocity: ${getYVelocity(pointerId)}")

}

}

MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {

// Return a VelocityTracker object back to be re-used by others.

mVelocityTracker?.recycle()

mVelocityTracker = null

}

}

return true

}

}

Java

public class MainActivity extends Activity {

private static final String DEBUG_TAG = "Velocity";

...

private VelocityTracker mVelocityTracker = null;

@Override

public boolean onTouchEvent(MotionEvent event) {

int index = event.getActionIndex();

int action = event.getActionMasked();

int pointerId = event.getPointerId(index);

switch(action) {

case MotionEvent.ACTION_DOWN:

if(mVelocityTracker == null) {

// Retrieve a new VelocityTracker object to watch the

// velocity of a motion.

mVelocityTracker = VelocityTracker.obtain();

}

else {

// Reset the velocity tracker back to its initial state.

mVelocityTracker.clear();

}

// Add a user's movement to the tracker.

mVelocityTracker.addMovement(event);

break;

case MotionEvent.ACTION_MOVE:

mVelocityTracker.addMovement(event);

// When you want to determine the velocity, call

// computeCurrentVelocity(). Then call getXVelocity() and

// getYVelocity() to retrieve the velocity for each pointer ID.

mVelocityTracker.computeCurrentVelocity(1000);

// Log velocity of pixels per second. It's best practice to use

// VelocityTrackerCompat where possible.

Log.d("", "X velocity: " + mVelocityTracker.getXVelocity(pointerId));

Log.d("", "Y velocity: " + mVelocityTracker.getYVelocity(pointerId));

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

// Return a VelocityTracker object back to be re-used by others.

mVelocityTracker.recycle();

break;

}

return true;

}

}

注意 :计算 ACTION_MOVE 事件发生后(而不是在发生后)的速度

ACTION_UP。在

ACTION_UP 时,X 速度和 Y 速度为 0。

使用指针捕获

有些应用(例如游戏、远程桌面和虚拟化客户端)会受益

对鼠标指针的控制指针捕获是一项功能

Android 8.0(API 级别 26)及更高版本中提供的功能,它通过

将所有鼠标事件传递到应用中的聚焦视图。

请求指针捕获

应用中的视图只有在

包含它的焦点因此,当存在

用户执行特定操作时,例如在

onClick()

onWindowFocusChanged()

事件处理脚本。

要请求指针捕获,请调用

requestPointerCapture()

方法。以下代码示例展示了如何请求指针

用户点击视图时触发的事件:

Kotlin

fun onClick(view: View) {

view.requestPointerCapture()

}

Java

@Override

public void onClick(View view) {

view.requestPointerCapture();

}

在捕获指针的请求成功后,Android 会调用

onPointerCaptureChange(true)。

只要满足以下条件,系统就会将鼠标事件传递到应用中聚焦的视图:

它与请求捕获的视图位于同一视图层次结构中。其他

应用会停止接收鼠标事件,直到捕获释放为止,这些事件包括

ACTION_OUTSIDE

事件。Android 将鼠标以外来源的指针事件作为

正常,但鼠标指针不再可见。

处理捕获的指针事件

在视图成功获取指针捕获后,Android 会提供

鼠标事件。聚焦的视图可以通过执行以下其中一项操作来处理事件:

以下任务:

如果您使用的是自定义视图,请替换

onCapturedPointerEvent(MotionEvent)。

否则,请注册

OnCapturedPointerListener。

以下代码示例展示了如何实现

onCapturedPointerEvent(MotionEvent):

Kotlin

override fun onCapturedPointerEvent(motionEvent: MotionEvent): Boolean {

// Get the coordinates required by your app.

val verticalOffset: Float = motionEvent.y

// Use the coordinates to update your view and return true if the event is

// successfully processed.

return true

}

Java

@Override

public boolean onCapturedPointerEvent(MotionEvent motionEvent) {

// Get the coordinates required by your app.

float verticalOffset = motionEvent.getY();

// Use the coordinates to update your view and return true if the event is

// successfully processed.

return true;

}

以下代码示例展示了如何注册

OnCapturedPointerListener:

Kotlin

myView.setOnCapturedPointerListener { view, motionEvent ->

// Get the coordinates required by your app.

val horizontalOffset: Float = motionEvent.x

// Use the coordinates to update your view and return true if the event is

// successfully processed.

true

}

Java

myView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() {

@Override

public boolean onCapturedPointer (View view, MotionEvent motionEvent) {

// Get the coordinates required by your app.

float horizontalOffset = motionEvent.getX();

// Use the coordinates to update your view and return true if the event is

// successfully processed.

return true;

}

});

无论您是使用自定义视图还是注册监听器,您的视图都会收到

MotionEvent,使用指定相对移动的指针坐标,例如 X

或 Y 增量,类似于轨迹球设备传递的坐标。您可以

使用

getX()和

getY()。

释放捕获的指针

应用中的视图可以通过调用

releasePointerCapture()、

如以下代码示例所示:

Kotlin

override fun onClick(view: View) {

view.releasePointerCapture()

}

Java

@Override

public void onClick(View view) {

view.releasePointerCapture();

}

在您未明确指明的情况下,系统可能会将捕获的画面从视图中移除

调用 releasePointerCapture(),这通常是因为视图层次结构

包含请求捕获的视图会失去焦点。

相关推荐

启迈斯t600和q7对比哪个好,q7跑步机好吗
bet878365

启迈斯t600和q7对比哪个好,q7跑步机好吗

📅 09-17 👁️ 4756
JBL音箱的售后问题。。。。。。。
365bet官网娱乐

JBL音箱的售后问题。。。。。。。

📅 09-29 👁️ 8709
背光键盘怎么开
365bet官网娱乐

背光键盘怎么开

📅 07-17 👁️ 1235