ViewGroup如何通过位置(x,y)获取child视图?
ViewGroup How to get child view by location (x, y)?
我正在制作 CustomLayout
,其中可以包含一些 child 视图。这些 child 视图可能相互重叠。这些 child 视图的变换矩阵可以通过 setRotation
setScale
等进行修改
我们如何通过本地位置 (x, y) 获得 child?:
class CustomLayout extends ViewGroup {
public View getChildByLocation(int x, int y) {
// HOW TO IMPLEMENT THIS
}
}
据我所知 ViewGroup
允许我们 getChildAt(index)
这样我就可以遍历它的 children 来找出我需要的视图。但它是如此复杂,我想要一种官方方式来通过位置(x,y)获得 child。
提前致谢!
使用下面的 Utils class。只需要调用 1 次方法
无需子class 您的布局。从 main-thread 调用该方法,它也支持 translation/rotation/scale。
// return null if no child at the position is found
View outputView = Utils.findChildByPosition(theParentViewGroup, x, y)
class Utils 的完整源代码:
public final class Utils {
/**
* find child View in a ViewGroup by its position (x, y)
*
* @param parent the viewgourp
* @param x the x position in parent
* @param y the y position in parent
* @return null if not found
*/
public static View findChildByPosition(ViewGroup parent, float x, float y) {
int count = parent.getChildCount();
for (int i = count - 1; i >= 0; i--) {
View child = parent.getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
if (isPositionInChildView(parent, child, x, y)) {
return child;
}
}
}
return null;
}
private static boolean isPositionInChildView(ViewGroup parent, View child, float x, float y) {
sPoint[0] = x + parent.getScrollX() - child.getLeft();
sPoint[1] = y + parent.getScrollY() - child.getTop();
Matrix childMatrix = child.getMatrix();
if (!childMatrix.isIdentity()) {
childMatrix.invert(sInvMatrix);
sInvMatrix.mapPoints(sPoint);
}
x = sPoint[0];
y = sPoint[1];
return x >= 0 && y >= 0 && x < child.getWidth() && y < child.getHeight();
}
private static Matrix sInvMatrix = new Matrix();
private static float[] sPoint = new float[2];
}
我正在制作 CustomLayout
,其中可以包含一些 child 视图。这些 child 视图可能相互重叠。这些 child 视图的变换矩阵可以通过 setRotation
setScale
等进行修改
我们如何通过本地位置 (x, y) 获得 child?:
class CustomLayout extends ViewGroup {
public View getChildByLocation(int x, int y) {
// HOW TO IMPLEMENT THIS
}
}
据我所知 ViewGroup
允许我们 getChildAt(index)
这样我就可以遍历它的 children 来找出我需要的视图。但它是如此复杂,我想要一种官方方式来通过位置(x,y)获得 child。
提前致谢!
使用下面的 Utils class。只需要调用 1 次方法
无需子class 您的布局。从 main-thread 调用该方法,它也支持 translation/rotation/scale。
// return null if no child at the position is found
View outputView = Utils.findChildByPosition(theParentViewGroup, x, y)
class Utils 的完整源代码:
public final class Utils {
/**
* find child View in a ViewGroup by its position (x, y)
*
* @param parent the viewgourp
* @param x the x position in parent
* @param y the y position in parent
* @return null if not found
*/
public static View findChildByPosition(ViewGroup parent, float x, float y) {
int count = parent.getChildCount();
for (int i = count - 1; i >= 0; i--) {
View child = parent.getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
if (isPositionInChildView(parent, child, x, y)) {
return child;
}
}
}
return null;
}
private static boolean isPositionInChildView(ViewGroup parent, View child, float x, float y) {
sPoint[0] = x + parent.getScrollX() - child.getLeft();
sPoint[1] = y + parent.getScrollY() - child.getTop();
Matrix childMatrix = child.getMatrix();
if (!childMatrix.isIdentity()) {
childMatrix.invert(sInvMatrix);
sInvMatrix.mapPoints(sPoint);
}
x = sPoint[0];
y = sPoint[1];
return x >= 0 && y >= 0 && x < child.getWidth() && y < child.getHeight();
}
private static Matrix sInvMatrix = new Matrix();
private static float[] sPoint = new float[2];
}