gpt4 book ai didi

java - Android onScroll 事件给出错误的值

转载 作者:行者123 更新时间:2023-11-29 05:23:14 38 4
gpt4 key购买 nike

我正在尝试使用 Android Canvas 和 GuestureDetector.SimpleOnGestureListener 实现自定义双向滚动,但我遇到了一些问题。似乎第一个滚动事件总是会产生巨大的不准确跳跃。

例如,如果我在 Canvas 中间单击并稍微滚动一点,我将看到这样的滚动事件(略微四舍五入):

scroll x: -352 scroll y: -373
scroll x: -4 scroll y: 3
scroll x -4 scroll y: 3

滚动的第一个值总是一个巨大的跳跃,我不是用我滚动的手指远程执行的。它似乎正在处理我的第一个滚动 Action ,就像我将手指从 Canvas 的一角移动到手指实际所在的位置一样?

这是我真正的听众:

public class BoardScrollListener extends GestureDetector.SimpleOnGestureListener {

private GameService gameService = GameService.getInstance();
private UiService uiService = UiService.getInstance();

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

Log.d("scroll", "scroll x: " + distanceX + " scroll y: " + distanceY);
if (distanceX > -150 && distanceY > -150) {
Game game = gameService.getGame();
game.setxPixelOffset((int) (game.getxPixelOffset() - distanceX));
game.setyPixelOffset((int) (game.getyPixelOffset() - distanceY));

uiService.getGameboardActivity().getGameboard().invalidate();
}
return true;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
}

我尝试将其包装在 if 检查中以查看发生了什么,这实际上在大多数情况下都解决了问题,但显然这不是真正的解决方案。谁能告诉我为什么运动事件不准确,以及使其准确或忽略滚动的第一个运动事件的好方法?

我正在使用 v4 支持 Activity fragment ,所以我也尝试切换到 GestureDetectorCompat,但这并没有改变任何东西。 (这是在 KitKat 设备上。)

最佳答案

我遇到了同样的问题。就我而言,我发现这是因为我正在使用 onInterceptTouchEvent()。我需要这个,因为 ACTION_DOWN 事件应该由我的 View 组的 child 处理。但是,当拦截 ACTION_MOVE 事件并将其提供给 GestureDetector 时,不会发送 ACTION_MOVE 之前的 MOTION_DOWN 事件。在 GestureListener 的 onScroll() 中,e1 始终为空。

在 onScroll() 中,第一个 distanceX 是根据 e1 的 positionX 计算的。之后使用前一个 e2 的 positionX。如果缺少 e1,onScroll() 使用 0 或上一次滚动发生 ACTION_UP 的位置(如果存在)。

无论如何,长话短说。为了让它工作,我决定忽略 onScroll() 中的第一个 ACTION_MOVE。请参阅下面我使用的代码。

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {

final int action = MotionEventCompat.getActionMasked(event);

// always handel touch event completion
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
//Log.i("Intercept Up: ", "END GESTURE");
mIsScrolling = false;
return false;
}

switch (action) {
case MotionEvent.ACTION_DOWN: {
// Record position
mDownX = event.getX();
// let the child handel the event
return false;
}
case MotionEvent.ACTION_MOVE: {
if (mIsScrolling) {
// we are currently scrolling, so intercept the event
return true;
}
float dx = event.getX() - mDownX;
if (Math.abs(dx) > mTouchSlop) {
// We met the motion threshold; Intercept the event to initiate scrolling
mIsScrolling = true;
return true;
}
// Not scrolling and threshold not met
return false;
}
default: {
// other motion events will not be intercepted
return false;
}
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {

final int action = MotionEventCompat.getActionMasked(event);

// always handel touch event completion
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mIsScrolling = false;
// Used to ignore the first scroll event with bad distanceX
mIsFirstScrollEvent = true;
return true;
}
// Use GestureDetector to detect event type
mGestureDetector.onTouchEvent(event);
return true;
}


private final GestureDetector.OnGestureListener mGestureListener =
new GestureDetector.SimpleOnGestureListener() {

@Override
public boolean onScroll (MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {

// First scroll event should be ignored because of bad distanceX
if (mIsFirstScrollEvent) {
mIsFirstScrollEvent = false;
return true;
}

// Do the scroll stuff here

return true;
}
};

关于java - Android onScroll 事件给出错误的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23824123/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com