view.getHitRect(rect)无效

5

我正在重写onInterceptTouch(MotionEvent)以实现水平滚动的目的。然而,我发现无法检测用户何时触摸嵌入的视图。视图上的x、y像2000、2400,而MotionEvent.getX(),getY()像400,500。

View v = findViewById(R.id.myView);

Rect r = new Rect();
v.getHitRect(r);
int[] loc = new int[2];
v.gtLocationOnScreen(loc);

int x = loc[0];
int y = loc[1];

// Result x,y are huge numbers 2400, etc
// event.getX() is 30, event.getY() == 500 nothing close to 2400.

if (r.contains((int)event.getX(), (int)event.getY())
{
   return false;  // this is never true even when I click right on View v.
 }
2个回答

19

我知道这是一个老问题,而且大部分已在链接的帖子中得到了回答,但我刚遇到了这个问题,所以我想分享我的解决方案。

private boolean isTouchInView(View view, MotionEvent event) {
    Rect hitBox = new Rect();
    view.getGlobalVisibleRect(hitBox);
    return hitBox.contains((int) event.getRawX(), (int) event.getRawY());
}

你救了我的命。我找了很久才找到你的答案,谢谢! - Tal Angel
你有没有想过为什么这在某些设备上可以运行,而在其他很多设备上却不能?看起来后者有一个偏移量。 - Davide Berra

3

尝试使用getRawX()getRawY()。这些将给你所需的绝对位置。

参见:

如何知道MotionEvent是相对还是绝对的?

你还必须调整目标视图的位置,以考虑其他视图的任何位移,如下所示:

int[] screenLocation = new int[2];
view.getLocationOnScreen(screenLocation);
hitRect.offset(screenLocation[0] - view.getLeft(), screenLocation[1] - view.getTop());

//Then check if source view is contained in target view

x=event.getRawX();
y=event.getRawY();

if (hitRect.contains(x, y)) {

//do your stuff

}

视图的结果(x,y)为(2180,2425),MotionEvent.getRawX,Y =(149,1017),再次r.contains失败。 - Android Developer
问题在于Anup,它对于任何视图v都不起作用。如果视图是主父视图之外的视图,则可以工作,但对于嵌套视图则无法工作。 - Android Developer
如果您认为您有答案,请提供一个通用的公共布尔值isWithinView(View v,MotionEvent e){},适用于任何级别的任何视图。我会将其插入。 - Android Developer
我并不希望 API 级别的调用依赖于对布局的每一层进行检查。我需要一个通用的解决方案。我仍在寻找更通用的解决方案。 - Android Developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接