myView.getHitRect() 返回相对于父级的坐标。如何获得相对于祖父母的坐标?

5
我正在使用以下代码创建视图的触摸委托。问题在于,我想要增加可点击区域的视图位于非常狭窄的LinearLayout内部。因此,下面的代码可以增加我的视图的可点击区域,但仅在我狭窄的LinearLayout范围内。我想将myView.getParent().getParent()(RelativeLayout)而不是父级传递给此函数,因为它有更大的可点击区域空间。但是,touchRect将指向错误的位置,我的TouchDelegate将被错误地定位。原因是:delegate.getHitRect(touchRect); 返回相对于父级而不是父级(或父级的父级)的位置。
public static Runnable getTouchDelegateAction(final View delegate, final View parent, final int topPadding, final int bottomPadding, final int leftPadding,
        final int rightPadding) {
    return new Runnable() {
        @Override
        public void run() {

            // Construct a new Rectangle and let the Delegate set its values
            Rect touchRect = new Rect();
            delegate.getHitRect(touchRect);

            // Modify the dimensions of the Rectangle
            // Padding values below zero are replaced by zeros
            touchRect.top -= Math.max(0, topPadding);
            touchRect.bottom += Math.max(0, bottomPadding);
            touchRect.left -= Math.max(0, leftPadding);
            touchRect.right += Math.max(0, rightPadding);


            // Now we are going to construct the TouchDelegate
            TouchDelegate touchDelegate = new TouchDelegate(touchRect, delegate);

            // And set it on the parent
            parent.setTouchDelegate(touchDelegate);
        }
    };
}

有什么建议吗?
2个回答

4
如果有人遇到类似的问题,这里有一个我找到的解决方案。不同之处在于标志绑定到祖父节点,可以设置以将委托放置到可点击视图的祖父节点。
public static Runnable getTouchDelegateAction(final View delegate, final boolean bindToGrandparent, final int topPadding,
        final int bottomPadding, final int leftPadding, final int rightPadding) {
    return new Runnable() {
        @Override
        public void run() {
            View parent = (View) delegate.getParent();
            View grandparent = (View) parent.getParent();

            // Construct a new Rectangle and let the Delegate set its values
            Rect touchRect = new Rect();
            delegate.getHitRect(touchRect);

            if (bindToGrandparent) {
                touchRect.top += parent.getTop();
                touchRect.left += parent.getLeft();
                touchRect.bottom += parent.getTop();
                touchRect.right += parent.getLeft();
            }

            // Modify the dimensions of the Rectangle
            // Padding values below zero are replaced by zeros
            touchRect.top -= Math.max(0, topPadding);
            touchRect.bottom += Math.max(0, bottomPadding);
            touchRect.left -= Math.max(0, leftPadding);
            touchRect.right += Math.max(0, rightPadding);

            // Now we are going to construct the TouchDelegate
            TouchDelegate touchDelegate = new TouchDelegate(touchRect, delegate);

            // And set it on the parent
            if (bindToGrandparent) {
                grandparent.setTouchDelegate(touchDelegate);
            } else {
                parent.setTouchDelegate(touchDelegate);
            }
        }
    };
}

应该按照以下方式使用:

grandparentView.post(FuncHelper.getTouchDelegateAction(ivFavorite, true, 30, 30, 30, 30));

重要的是在视图的祖先上发布过程。

或者:

parentView.post(FuncHelper.getTouchDelegateAction(ivFavorite, false, 30, 30, 30, 30));

1
如果您需要在与祖父母甚至祖先有关的视图中创建触摸委托,您只需在代码中添加一行即可:((ViewGroup)parent).offsetDescendantRectToMyCoords(delegate, touchRect); 因此,最终代码可能看起来像这样:
public static Runnable getTouchDelegateAction(final View delegate, final View parent, 
                                              final int topPadding, final int bottomPadding, 
                                              final int leftPadding, final int rightPadding) {

    return new Runnable() {
        @Override
        public void run() {
            Rect touchRect = new Rect();
            delegate.getHitRect(touchRect);

            // Modify the dimensions of the Rectangle
            // Padding values below zero are replaced by zeros
            touchRect.top -= Math.max(0, topPadding);
            touchRect.bottom += Math.max(0, bottomPadding);
            touchRect.left -= Math.max(0, leftPadding);
            touchRect.right += Math.max(0, rightPadding);

            // calculates the relative coordinates to the parent
            ((ViewGroup) parent).offsetDescendantRectToMyCoords(delegate, touchRect);
            parent.setTouchDelegate(new TouchDelegate(touchRect, delegate));
        }
    };
}

这里你可以找到官方文档。


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