【问题标题】:ViewGroup How to get child view by location (x, y)?ViewGroup 如何按位置(x,y)获取子视图?
【发布时间】:2017-01-17 06:35:21
【问题描述】:

我正在制作CustomLayout,它可以包含一些子视图。这些子视图可能相互重叠。这些子视图的变换矩阵可以通过setRotationsetScale等修改。

我们如何通过本地位置 (x, y) 获取孩子?:

class CustomLayout extends ViewGroup {
    public View getChildByLocation(int x, int y) {
        // HOW TO IMPLEMENT THIS
    }
}

据我所知,ViewGroup 允许我们使用getChildAt(index),这样我就可以遍历它的子元素以找出我需要的视图。但这太复杂了,我想要一个官方的方法来通过位置(x,y)得到一个孩子。

提前谢谢你!

【问题讨论】:

    标签: java android view viewgroup


    【解决方案1】:

    在下面使用这个 Utils 类。只需要 1 个方法调用

    无需子类化您的布局。从主线程调用该方法,它也支持平移/旋转/缩放。

    // return null if no child at the position is found
    View outputView = Utils.findChildByPosition(theParentViewGroup, x, y)
    

    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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 2020-07-29
      • 1970-01-01
      • 2019-08-06
      • 1970-01-01
      • 2022-08-02
      相关资源
      最近更新 更多