从Android 3.0开始,我们可以使用setRotationX和setRotationY为视图设置基本的3D转换。
在特定情况下,我需要实现一个复杂的变换,即围绕一个远点,然后在不同的枢轴点上缩放。简单地使用setScaleX / Y和setRotationX / Y是不可能的,因为它们共享相同的轴心点。
是否有任何简单的方法可以为视图提供所需的矩阵以供显示?
目前,我找到了两种可能的解决方法:
设置旋转矩阵,然后用它来映射{0,0}点;将结果点应用于View的翻译,然后使用View的setScaleX / Y设置缩放
破解View的onDraw并在画布上应用转换。添加逻辑以反转地图触摸事件。
两者都不是很方便,因为我正在构建一个使用可配置效果显示其项目的AdapterView;例如,可以切换效果以使项目以圆圈形式排列或像“封面流程”一样。
答案 0 :(得分:9)
我也是在为此辩护。这是我提出的最好的(超级hacky):
MyAnimation animation = new MyAnimation(matrix);
animation.setDuration(0);
animation.setFillAfter(true);
view.setAnimation(animation);
答案 1 :(得分:5)
上面的动画解决方案有效,但它会导致对applyTransformation
的无限调用,从效率的角度来看,这会留下一些不足之处。此外,如果您杀死动画,则应用的矩阵对于视图不是永久性的,因此您不得不让它永远运行。这是另一种不那么糟糕的方法,每次调用视图setMatrix
时,只会调用一次invalidate()
:
在父视图构造函数中:
setStaticTransformationsEnabled(true);
然后在身体里:
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
// apply transform to child view - child triggers this call by call to `invalidate()`
t.getMatrix().set(someMatrix);
return true;
}
只要您想要更新它的矩阵,只需在孩子身上调用invalidate()
。
答案 2 :(得分:3)
xtravar的答案很棒,MyAnimation实施就在这里
private class MyAnimation extends Animation {
private Matrix matrix;
public MyAnimation(Matrix matrix) {
this.matrix = matrix;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
t.getMatrix().set(matrix);
}
}