如何在变换矩阵后获得视图的正确边界

2024-02-18

我有一个使用转换的自定义视图。到目前为止一切顺利,功能就像setRotationY(), setScaleX(), setTranslationY()甚至getMatrix()按预期工作,我可以操纵我的视图并且它显示得很好。 我遇到的问题是,此后许多函数的行为变得奇怪。例如像这样的函数getHitRect()返回完全奇怪的值!这对我的触摸事件没有帮助。

我尝试重载该函数,但它仍然无法正常工作,特别是在使用旋转或缩放时(翻译工作正常)。我认为这与矩阵以子坐标表示的事实有关,那么如何在父坐标中得到它呢?

@Override
    public void getHitRect(Rect outRect){

        RectF rect = new RectF(); 
        rect.top = (float) this.getTop(); 
        rect.bottom = (float) this.getBottom(); 
        rect.left = (float) this.getLeft(); 
        rect.right = (float) this.getRight();      

    this.getMatrix().mapRect(rect);
        rect.round(outRect);
    }

我可以直接从某个函数获得一些更直接的值吗?比如新的高度、宽度、顶部或底部。


当重写 ViewGroup 的“getChildStaticTransformation”方法,甚至使用像这样的转换函数时setRotationY(), setScaleX(), setTranslationY(), getMatrix()(可从 API 11 获取)您只会影响渲染矩阵。因此,您的自定义子视图将返回远离您的孩子绘制位置的边界“矩形”。大多数时候这不是问题,但是当您开始愿意单击它时......麻烦就开始了......以下是我解决该问题的方法。我确信可能有更好的方法,但因为我在这里还没有找到关于这个主题的很多东西。

在 ViewGroup 重载中:

public interface Itransformable {
    public void setTransformationMatrix(Matrix trsMatrix);
}

@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
    if (child instanceof Itransformable){   
        t.clear();
        t.setTransformationType(Transformation.TYPE_MATRIX);
        ...
        // Do whatever transformation you want here
        ...
        ((Itransformable)child).setTransformationMatrix(t.getMatrix());
        return true;
    } else {
        return false;
    }
}

这是子自定义视图: 请注意,我没有直接在自定义视图中存储变换矩阵,而是存储变换后的矩形。如果您想存储矩阵(即用于以后的转换,例如点...),您可能需要克隆它,因为矩阵将以某种奇怪的方式进行更改,例如回收或其他方式。

public class MyCustomView extends View implements MyViewGroup.Itransformable{

private Rect mViewRect = null;

public void setTransformationMatrix(Matrix trsMatrix){
    if (trsMatrix!=null){
        RectF rect = new RectF();
        rect.top = 0;
        rect.bottom = (float) this.getHeight(); 
        rect.left = 0; 
        rect.right = (float) this.getWidth();  

        trsMatrix.mapRect(rect);
        rect.offset((float) this.getLeft(), (float) this.getTop());

        if (mViewRect == null) mViewRect = new Rect();
        rect.round(mViewRect);
    }
}

public Rect getTransformatedRect() {
    if (mViewRect!=null){
        // OutOfScreen WorkArround - As the view is not Displayed, mViewRect doesn't get updated.
        if(getRight() < 0 || getLeft() > mParentWidth){
            return new Rect(getLeft(),getTop(),getRight(),getBottom());
        } else {
            return mViewRect;
        }
    } else {
        return new Rect(getLeft(),getTop(),getRight(),getBottom());
    }
}

@Override
public void getHitRect(Rect outRect){

    if (mViewRect == null){
        super.getHitRect(outRect);
    } else {
        outRect.set(getTransformatedRect());
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在变换矩阵后获得视图的正确边界 的相关文章

随机推荐