Android:如何使用矩阵来动画移动视图?

3

如何使用动画将视图从当前位置(平移,旋转和缩放)移动到矩阵的新状态?

当前值(...) ==> 动画 ==> 新值(缩放:1,transX: 20,transY: 700,角度:0)

我使用以下代码,但移动没有动画效果。

Matrix matrix = new Matrix();
matrix.setTranslate(20, 700);

MyAnimation animation = new MyAnimation(matrix);
animation.setDuration(1000);
animation.setFillAfter(true);
text_object.setAnimation(animation);

MyAnimation.java

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

如何使动画效果生效? 有哪些替代方案可以实现这个目标?

2个回答

3

尽管这个问题已经过时,但它对我很有帮助,因此我会评论一下以便其他人可以受益。

为了给你的矩阵添加动画效果,你需要根据interpolatedTime更改它。问题在于每次运行动画时,你都将矩阵设置为相同的值,这就是为什么它没有起作用的原因。 有几种操作矩阵的方法,例如

Matrix.setRectToRect()
Matrix.setPolyToPoly()
Matrix.setValues()

或者使用更标准的API。

这是我正在使用的一个类:


import android.graphics.Matrix;
import android.graphics.PointF;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class MatrixAnimation extends Animation {
    private PointF scaleStart;
    private PointF scaleEnd;
    private PointF translateStart;
    private PointF translateEnd;
    private boolean animated = true;

    MatrixAnimation(Matrix startMatrix, Matrix endMatrix){
        this(startMatrix, endMatrix, true);
    }

    MatrixAnimation(Matrix startMatrix, Matrix endMatrix, boolean animated){
        float[] a = new float[9];
        float[] b = new float[9];

        startMatrix.getValues(a);
        endMatrix.getValues(b);

        scaleStart = new PointF(a[Matrix.MSCALE_X], a[Matrix.MSCALE_Y]);
        scaleEnd =  new PointF(b[Matrix.MSCALE_X], b[Matrix.MSCALE_Y]);
        translateStart = new PointF(a[Matrix.MTRANS_X], a[Matrix.MTRANS_Y]);
        translateEnd = new PointF(b[Matrix.MTRANS_X], b[Matrix.MTRANS_Y]);

        setFillAfter(true);
        //setInterpolator(new DecelerateInterpolator());
    }

    protected MatrixAnimation setAnimated(boolean animated){
        this.animated = animated;
        setDuration(animated ? 300 : 0);
        return this;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        final Matrix matrix = t.getMatrix();
        PointF sFactor = new PointF(
                scaleEnd.x * interpolatedTime / scaleStart.x + 1 - interpolatedTime,
                scaleEnd.y * interpolatedTime / scaleStart.y + 1 - interpolatedTime);
        PointF tFactor = new PointF(
                (translateEnd.x - translateStart.x) * interpolatedTime,
                (translateEnd.y - translateStart.y) * interpolatedTime);

        //Log.d(TAG, "applyTransformation: " + sFactor + " " + tFactor);

        matrix.postScale(scaleStart.x, scaleStart.y, 0, 0);
        matrix.postScale(sFactor.x, sFactor.y, 0, 0);
        matrix.postTranslate(translateStart.x, translateStart.y);
        matrix.postTranslate(tFactor.x, tFactor.y);
    }

    @Override
    public void start() {
        setAnimated(true);
        super.start();
    }

    public void start(boolean animated){
        setAnimated(animated);
        super.start();
    }
}


1
太好了!您的回答确实帮助了我! - W.Cameron
哇,这真是太神奇了!太棒了!感谢您挽救了我的一天。 - ucMedia
1
如何使用?我尝试使用类实例,但失败了。 - Mubashir Murtaza

0

使用“view.animate().x(20).y(700).start();”是相对于当前对象的计算,而不是屏幕。如何在全局坐标系中指定坐标? - Qulery
是的,这是相对于视图的。如果您想相对于屏幕使用,可以先找到视图的坐标。然后使用此坐标和相对位置进行动画处理。您可以尝试使用 View.getLocationOnScreen()getLocationInWindow() - Henry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接