如何获得视图的变换矩阵后能正常范围矩阵、视图、如何获得、范围

2023-09-04 11:36:18 作者:无所畏惧?

我有,我用转换的自定义视图。到目前为止好,像 setRotationY功能() setScaleX() setTranslationY() 甚至 getMatrix()如预期的工作,我可以操纵我的看法,它显示的罚款。 当我打的墙,一些功能之后,其行为怪异。对于像 getHitRect例如函数()返回完全怪异的值!这不是帮助我的触摸事件。

I have a custom view where I use transformations. So far so good, function like setRotationY(), setScaleX(), setTranslationY() or even getMatrix() work as expected, I’m able manipulate my view and it displays fine. Where I hit the wall is that a number of function behave strangely after that. For example function like getHitRect() return totally weird values! This is not helping my touch events.

我试图重载函数,但仍远远采用旋转时,尤其是工作或缩放(翻译工作的罚款通过)。我想,这是什么做的事实,矩阵是pssed儿童坐标EX $ P $,所以我怎么能得到它的父母协调?

I tried to overload the function but it is still far from working especially when using rotation or scaling (Translation working fine through). I think this as something to do with the fact that the matrix is expressed in child coordinate, so how can I get it in parents coordinate?

@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);
    }

我可以直接从一些功能得到一些直价值?像新的高度,宽度,顶部或底部。

Can I get some straighter value directly from some function? Like the new Height, Width, top or bottom.

推荐答案

在覆盖的ViewGroup的getChildStaticTransformation的方法,甚至使用转换函数如 setRotationY() setScaleX() setTranslationY() getMatrix() (可从API 11)你只影响呈现矩阵。这样一来您的自定义子视图将返回边界Rects不远的地方你的孩子得到平局。这是不是一个问题,大部分的时间,但是当你开始愿意去点击它..麻烦开始......这是我如何解决该问题。我敢肯定,有可能是一个更好的办法,但是,因为我还没有找到关于这一问题的很多事情就是这样。

When overriding the "getChildStaticTransformation" method of the ViewGroup or even using transformation function like setRotationY(), setScaleX(), setTranslationY(), getMatrix() (available from API 11) you are only affecting the rendering Matrix. As a result your custom Child View will return Bounds "Rects" far from where your child is getting draw. This is not an issue most of the time but when you start to be willing to click on it.. trouble are starting... Here is how I workaround the issue. I’m sure there might be a better ways but as I haven’t found many things on the subject here it is.

在的ViewGroup过载:

In the ViewGroup Overload:

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

下面是儿童自定义视图: 请注意,我没有直接存储在自定义视图变换矩阵,而是转化的矩形。如果你想要去的存储矩阵(即像点以后改造......),你可能需要克隆它为基体将在一些奇怪的方式得到改变就像是回收或东西。

Here is the Child Custom View: Note that I'm not storing directly the Transformation Matrix in the custom view but instead the transformed Rect. If you want to go for storing the matrix (i.e. for later transformation like point...) you might need to clone it as the matrix will get altered in some strange way like it is recycle or something.

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());
    }
}