Android: 如何使用矩阵动画移动View?
Android: How to animation move the View by using a matrix?
如何将带有动画的视图从当前位置(平移、旋转和缩放)移动到矩阵的新状态?
当前值 (...) ==> 动画 ==> 新值(比例: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);
}
}
如何制作动画?
可以使用哪些替代方法来实现此 objective?
为什么不厌其烦地修改 View
的 Matrix
来为其缩放和平移设置动画。只需使用 Property Animation
。您可以在这里阅读更多相关信息:http://developer.android.com/guide/topics/graphics/prop-animation.html
您可以使用 ObjectAnimator
来执行您需要的动画。
这个问题对我有帮助,所以尽管它已经过时了,但我还是会发表评论,以防它对其他人有帮助。
为了使您的矩阵动画化,您需要根据 interpolatedTime
对其进行更改。发生的情况是每次动画运行时您都将矩阵连续设置为相同的值,这就是它不起作用的原因。
有几种操作矩阵的方法,即
Matrix.setRectToRect()
Matrix.setPolyToPoly()
Matrix.setValues()
或使用更标准的 API。
这是我正在使用的class:
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,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);
}
}
如何制作动画? 可以使用哪些替代方法来实现此 objective?
为什么不厌其烦地修改 View
的 Matrix
来为其缩放和平移设置动画。只需使用 Property Animation
。您可以在这里阅读更多相关信息:http://developer.android.com/guide/topics/graphics/prop-animation.html
您可以使用 ObjectAnimator
来执行您需要的动画。
这个问题对我有帮助,所以尽管它已经过时了,但我还是会发表评论,以防它对其他人有帮助。
为了使您的矩阵动画化,您需要根据 interpolatedTime
对其进行更改。发生的情况是每次动画运行时您都将矩阵连续设置为相同的值,这就是它不起作用的原因。
有几种操作矩阵的方法,即
Matrix.setRectToRect()
Matrix.setPolyToPoly()
Matrix.setValues()
或使用更标准的 API。
这是我正在使用的class:
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();
}
}