android - 变换矩阵后如何获得 View 的正确边界

标签 android

我有一个使用转换的自定义 View 。到目前为止一切顺利,功能类似于 setRotationY()setScaleX()setTranslationY() 甚至 getMatrix() 按预期工作,我能够操纵我的 View 并且它显示正常。 我碰壁的地方是在那之后许多功能表现得很奇怪。例如像 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 获得)您只影响渲染矩阵。因此,您的自定义 subview 将返回远离您的 child 绘制位置的边界“矩形”。大多数时候这不是问题,但是当您开始愿意单击它时……麻烦就开始了……这就是我解决该问题的方法。我敢肯定可能有更好的方法,但由于我没有在这里找到很多关于这个主题的东西。

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

这是子自定义 View : 请注意,我没有直接将转换矩阵存储在自定义 View 中,而是存储转换后的 Rect。如果你想去存储矩阵(即为了以后的转换,比如点......)你可能需要克隆它,因为矩阵会以某种奇怪的方式改变,比如它是回收或其他东西。

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

关于android - 变换矩阵后如何获得 View 的正确边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8096469/

相关文章:

java - Android 应用程序按钮不起作用

android - GCM - 已显示通知有效载荷,但如何处理 "click"

android - 使用产品口味时,应用程序名称不会在启动器中更改

android - onActivityResult() 在意外的时间被调用

android - 为什么 Firebase 分析的自定义事件未显示在仪表板上?

java - 获取 Facebook 通知 API 3.0

android - Kotlin 合并两个可为空的可变列表

android - 为什么在android中检查互联网访问时,它总是返回 "true"?

javascript - undefined 不是一个函数(评估 React.createClass)

Android HttpResponse - 内容已被消费