17

从 Android 3.0 开始,我们可以使用 setRotationX 和 setRotationY 为视图设置基本的 3D 转换。

在特定情况下,我需要实现一个复杂的转换,即围绕远处的枢轴点旋转,然后在不同的枢轴点上缩放。简单地使用 setScaleX/Y 和 setRotationX/Y 是不可能的,因为它们共享相同的枢轴点。

是否存在任何简单的方法来为视图提供所需的矩阵以进行显示?

目前,我找到了两种可能的解决方法:

  • 设置一个旋转矩阵,然后用它来映射一个 {0,0} 点;将结果点应用于视图的平移,然后使用视图的 setScaleX/Y 设置缩放

  • 破解视图的 onDraw 并在画布上应用转换。也添加反转地图触摸事件的逻辑。

两者都不是很方便,因为我正在构建一个使用可配置效果显示其项目的 AdapterView;例如,可以切换效果以使项目排列成圆形或像“封面流”。

4

3 回答 3

10

我也在为此绞尽脑汁。这是我想出的最好的(超级hacky):

 MyAnimation animation = new MyAnimation(matrix);
 animation.setDuration(0);
 animation.setFillAfter(true);
 view.setAnimation(animation);
于 2014-02-11T18:06:59.307 回答
6

上面的动画解决方案有效,但它会导致无限调用,applyTransformation从效率的角度来看,这还有一些不足之处。此外,如果您终止动画,则应用的矩阵对视图不是永久的,因此您被迫让它永远运行。这是另一种不那么 hacky 的方法,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()只要您想更新它的矩阵,只需调用孩子。

于 2016-07-13T23:41:26.910 回答
4

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);
    }
}
于 2015-02-10T07:41:19.340 回答