您的位置:首页 > 移动开发 > Android开发

Android自定义动画--卡牌翻牌动画

2015-09-04 16:01 369 查看
Android系统中自带了四种动画,但是都只是平面上的并不能实现我们很常见的翻牌动画,所以今天我们就要通过自定义动画来实现翻牌动画.

要实现翻牌动画,我们需要了解三个类,一个是matrix类,一个是camera类,一个是animation类.

1.matrix类是一个3x3的矩阵,用于控制图像和view的平移,旋转,放缩及斜割,官方封装了针对这些的操作给我们,我们只需要采用其中的matrix.setTranslate();matrix.setRotate();matrix.setScale();方法就可以完成一系列复杂的变换,如果想细致了解matrix的话可以参考http://www.360doc.com/content/11/1215/11/7635_172396706.shtml.下面举一个matrix实现图像变换的简单例子:

public class MyView extends View {

private Bitmap mBitmap;

private Matrix mMatrix = new Matrix();

public MyView(Context context) {

super(context);

initialize();

}

private void initialize() {

mBitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();

float cosValue = (float) Math.cos(-Math.PI/6);

float sinValue = (float) Math.sin(-Math.PI/6);

mMatrix.setValues(

new float[]{

cosValue, -sinValue, 100,

sinValue, cosValue, 100,

0, 0, 2});

}

@Override protected void onDraw(Canvas canvas) {

//		super.onDraw(canvas);  //当然,如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。

canvas.drawBitmap(mBitmap, mMatrix, null);

}

}
2.camera类,通过使用camera类可以对图片或view进行三维空间的变换,提供了以下常用方法:

1)getMatrix(Matrix matrix),将camera所做的变换应用到制定matrix中.

2)rotateX(float deg):将目标组件沿X轴旋转

3)rotateY(float deg):将目标组件沿Y轴旋转

4)rotateZ(float deg):将目标组件沿Z轴旋转

5)translate(float x,float y,float z):把目标组件在三维空间里进行位移变换

6)applyToCanvas(Canvas canvas):把camera所做的变换应用到canvas中.

3.继承animation,继承animation时关键是要重写该抽象基类的applyTransformation(float interpolatedTime,Transformation t)方法,该方法中两个重要参数说明如下:

1)interpolatedTime:代表动画的时间进行比.不管动画实际持续时间如何,当动画播放的时候,该参数总是从0到1变化的.

2)Transformation :该参数代表了补间动画在不同时刻对图形或组件的变形程度.该对象里封装了一个Matrix对象,对他所包装的Matrix对象进行位移,倾斜,旋转等变换时,Transformation将会控制对应的图片或视图进行相应的变换.

接下来,我们看一下我们实现自定义动画的代码:
public class CardInvertAnimation extends Animation{
//动画的中心点
private float centerX,centerY;
//动画的持续时间
private int duration;
private Camera camera = new Camera();

public CardInvertAnimation(float centerX, float centerY, int duration) {
super();
this.centerX = centerX;
this.centerY = centerY;
this.duration = duration;
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
// TODO Auto-generated method stub
super.initialize(width, height, parentWidth, parentHeight);
//设置动画的持续时间
setDuration(duration);
//设置动画结束后效果保留
setFillAfter(true);
//设置动画差值器为线性
setInterpolator(new LinearInterpolator());

}
/* 该方法的interpolatedTime代表动画时间因子,不论duration时间为多少,它的取值范围都为0-1
* @interpolatedTime 总是从0-1
* @t 包含了view的矩阵,我们可以改变他的矩阵,进行动画.
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
// TODO Auto-generated method stub
super.applyTransformation(interpolatedTime, t);
camera.save();
//根据interpolatedTime来控制x,y,z上的偏移
//		camera.rotateY(180*interpolatedTime);;
//获取Transformation中的matrix,并将对应变换应用到matrix上
Matrix matrix = t.getMatrix();
camera.getMatrix(matrix);

matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
camera.restore();
}
}
这里我们要说明一下matrix.preTranslate(-centerX, -centerY);matrix.postTranslate(centerX, centerY);这两个方法的作用,我们知道我们view的坐标系是从(0,0)点开始的,也就是说,如果我们不将matrix的中心点提前移动(0,0)点,我们的翻牌动画会绕着view的左侧进行旋转,所以我们要使用这两个方法来进行matrix中心点的变化,pretranslate是指在rotate之前进行平移操作,postTranslate是在rotatle之后进行平移操作.这样就保证了我们得到的效果是沿着中心点的Y轴进行180度旋转的动画.

下面我们看一下如何使用这个 自定义动画,理想的状态下我们只需要找个view给他setAnimation就好了,但是我们要获取view的中心点,这里会出现一个问题,在oncreate方法中我们获取onMeasureHeight和onMeasureWidth得到值为0,原因是在oncreate方法中,我们的view并没有测量和加载完成,所以我们需要在view加载完成后第一时间得到通知,方便我们获取height和width,经过查阅,我们发现在view加载完成后会调用一个叫onWindowFocusChanged(Boolean
hasFocus)的方法,所以我们可以override找个方法,在里面进行height和width的获取,代码如下:
public class MainActivity extends Activity {
ImageView ig;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ig = (ImageView) findViewById(R.id.ig);

}

/* view加载完成后首先调用的方法
*
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
CardInvertAnimation a = new CardInvertAnimation(ig.getWidth() / 2,
ig.getHeight() / 2, 5000);
ig.setAnimation(a);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息