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实现图像变换的简单例子:
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将会控制对应的图片或视图进行相应的变换.
接下来,我们看一下我们实现自定义动画的代码:
下面我们看一下如何使用这个 自定义动画,理想的状态下我们只需要找个view给他setAnimation就好了,但是我们要获取view的中心点,这里会出现一个问题,在oncreate方法中我们获取onMeasureHeight和onMeasureWidth得到值为0,原因是在oncreate方法中,我们的view并没有测量和加载完成,所以我们需要在view加载完成后第一时间得到通知,方便我们获取height和width,经过查阅,我们发现在view加载完成后会调用一个叫onWindowFocusChanged(Boolean
hasFocus)的方法,所以我们可以override找个方法,在里面进行height和width的获取,代码如下:
要实现翻牌动画,我们需要了解三个类,一个是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); } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories