我有自定义视图,我在其中使用转换。到目前为止一切顺利,像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);
}
我可以直接从某个功能获得更直接的值吗?像新的高度,宽度,顶部或底部。
答案 0 :(得分:9)
当覆盖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;
}
}
以下是儿童自定义视图: 请注意,我不是直接将转换矩阵存储在自定义视图中,而是存储转换后的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());
}
}