android实时轨迹跟踪,跟踪轻触和指针移动  |  Android 开发者  |  Android Developers...

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

由于基于手指的轻触并不总是最精确的互动形式,因此检测触摸事件时通常更注重移动操作,而不仅仅是接触。为了帮助应用区分移动类手势(例如滑动)和非移动手势(例如点按一次),Android 引入了“touch slop”的概念。Touch slop 是指在系统将手势解读为基于移动的手势之前,用户的轻触手势可以滑动的距离(以像素为单位)。有关此内容的详细讨论,请参阅在 ViewGroup 中管理轻触事件。

根据应用的需求,您可以通过多种不同的方式跟踪手势中的移动操作。例如:

指针的起始位置和结束位置(例如,将屏幕中的对象从 A 点移到 B 点)。

指针行进的方向(由 x 和 y 坐标确定)。

历史事件。您可以通过调用 getHistorical 方法获取每个历史事件的位置、大小、时间和压力。历史事件在呈现用户手指的轨迹(例如,针对轻触绘制)时非常有用。如需了解详情,请参阅

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

请参阅以下相关资源:

跟踪速度

您可以设置单纯基于指针行进距离和/或方向的移动类手势。但是,速度通常是跟踪手势特征,甚至决定手势是否发生的决定因素。为了更方便地计算速度,Android 提供了

下面是一个简单的示例,说明了

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

// 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

// 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;

}

}

注意:您应该在

使用指针捕获

某些应用(例如游戏、远程桌面和虚拟化客户端)大大受益于对鼠标指针的控制。指针捕获是 Android 8.0(API 级别 26)及更高版本中提供的一项功能,可通过将所有鼠标事件传递到应用中聚焦的视图来提供此类控制功能。

请求指针捕获

应用中的视图只有在包含它的视图层次结构获得焦点时才能请求指针捕获。因此,您应该在视图中发生特定用户操作时请求指针捕获,例如在

如需请求指针捕获,请在视图中调用

Kotlin

fun onClick(view: View) {

view.requestPointerCapture()

}Java

@Override

public void onClick(View view) {

view.requestPointerCapture();

}

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

处理捕获的指针事件

在视图成功获取指针捕获后,Android 便会开始传递鼠标事件。聚焦的视图可以通过执行以下其中一项任务来处理事件:

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 was

// 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 was

// successfully processed

return true;

}

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 was

// 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 was

// successfully processed

return true;

}

});

无论您是使用自定义视图还是注册监听器,您的视图都会收到包含指针坐标的

释放捕获的指针

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

Kotlin

override fun onClick(view: View) {

view.releasePointerCapture()

}Java

@Override

public void onClick(View view) {

view.releasePointerCapture();

}

系统可以在您未显式调用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值