繁体   English   中英

如何通过坐标 x,y Android 在 View 中查找元素

[英]How to find element in View by coordinates x,y Android

如果我知道坐标(X,Y)像素(通过 OnTouchEvent 方法和 getX(),getY)我如何找到元素 ex。 按钮或文本等.... 使用X,Y

您可以使用每个子视图的getHitRect(outRect)并检查该点是否在结果矩形中。 这是一个快速示例。

for(int _numChildren = getChildCount(); --_numChildren)
{
    View _child = getChildAt(_numChildren);
    Rect _bounds = new Rect();
    _child.getHitRect(_bounds);
    if (_bounds.contains(x, y)
        // In View = true!!!
}

希望这可以帮助,

模糊逻辑

一个稍微更完整的答案,它接受任何ViewGroup并将递归搜索给定 x,y 处的视图。

private View findViewAt(ViewGroup viewGroup, int x, int y) {
    for(int i = 0; i < viewGroup.getChildCount(); i++) {
        View child = viewGroup.getChildAt(i);
        if (child instanceof ViewGroup) {
            View foundView = findViewAt((ViewGroup) child, x, y);
            if (foundView != null && foundView.isShown()) {
                return foundView;
            }
        } else {
            int[] location = new int[2];
            child.getLocationOnScreen(location);
            Rect rect = new Rect(location[0], location[1], location[0] + child.getWidth(), location[1] + child.getHeight());
            if (rect.contains(x, y)) {
                return child;
            }
        }
    }

    return null;
}

https://stackoverflow.com/a/10959466/2557258相同的解决方案,但在 kotlin 中:

fun ViewGroup.getViewByCoordinates(x: Float, y: Float) : View? {
    (childCount - 1 downTo 0)
        .map { this.getChildAt(it) }
        .forEach {
            val bounds = Rect()
            it.getHitRect(bounds)
            if (bounds.contains(x.toInt(), y.toInt())) {
                return it
            }
        }
    return null
}

修改@Luke 提供的答案。 不同之处在于使用getHitRect而不是getLocationOnScreen 我发现getLocationOnScreen对选择的视图不准确。 还将代码转换为 Kotlin 并使其成为ViewGroup的扩展:

/**
 * Find the [View] at the provided [x] and [y] coordinates within the [ViewGroup].
 */
fun ViewGroup.findViewAt(x: Int, y: Int): View? {
    for (i in 0 until childCount) {
        val child = getChildAt(i)

        if (child is ViewGroup) {
            val foundView = child.findViewAt(x, y)
            if (foundView != null && foundView.isShown) {
                return foundView
            }
        } else {
            val rect = Rect()

            child.getHitRect(rect)

            if (rect.contains(x, y)) {
                return child
            }
        }
    }
    return null
}

Android 使用 dispatchKeyEvent/dispatchTouchEvent 找到正确的视图来处理按键/触摸事件,这是一个复杂的过程。 因为可能有很多视图覆盖 (x, y) 点。

但是,如果您只想找到覆盖 (x, y) 点的最上方视图,这很简单。

1 使用 getLocationOnScreen() 获取绝对位置。

2 使用 getWidth()、getHeight() 判断视图是否覆盖 (x, y) 点。

3 计算整个视图树中的视图级别。 (递归调用 getParent() 或使用某种搜索方法)

4 找到既覆盖点又具有最大层的视图。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM