Android 属性动画及自定义3D旋转动画

Android 动画框架

其中包括,帧动画、视图动画(补间动画)、属性动画。

在Android3.0之前,视图动画一家独大,之后属性动画框架被推出。属性动画框架,基本可以实现所有的视图动画效果。

视图动画的效率较高且使用方便。但是相比属性动画,视图动画一个非常大的缺陷就是不具备交互性。当某个元素发生视图动画后,其响应事件的位置还依然在动画前的地方,所以视图动画只能做普通的动画效果,避免交互发生。

书接上篇:Android 动画之视图动画的使用


Animator 属性动画

其拥有ObjectAnimator单个动画和AnimatorSet动画集两个类。

使用 ObjectAnimator 可以控制单个View的某个属性值的变化,而将多个 ObjectAnimator 组合到一起就可以形成一个 AnimatorSet 动画集合。

ObjectAnimator

ObjectAnimator可以调用 setFrameDelay(longframeDelay) 设置动画帧之间的间隙时间,通过调整帧率的方式减少动画过程中频繁绘制界面。从而在不影响动画效果的前提下减少CPU资源消耗。

最重要的是,属性动画通过属性的get、set方法来真实地控制一个View的属性值。使用方法如下:

  • translationX和translationY:控制着View从布局容器的左上角坐标偏移的位置;
java 复制代码
ObjectAnimator animator=ObjectAnimator.ofFloat(view,"translationX",300);
animator.setDuration(300);
animator.start();
  • pivotX 和 privotY:控制着View的支点位置,默认支点为View的中心;
  • rorationX 和 rorationY :控制View围绕支点进行2D和3D旋转;
  • scaleX 和 scaleY:控制着View围绕它的支点进行2D缩放;
  • alpha:控制View的alpha透明度。默认值1不透明,0完全透明。

监听事件

java 复制代码
ObjectAnimator anima =ObjectAnimator.ofFloat(View,"alpha",0.5f);
anima.addListener(new AnimatorListener(){
    @Overrider
    public void onAnimationStart(Animator animation){//开始}
    @Overrider
    public void onAnimationRepeat(Animator animation){ //重复}
    @Overrider
    public void onAnimationEnd(Animator animation){//结束 }
    @Overrider
    public void onAnimationCancel(Animator animation){ //取消 }
});
anima.start();

也可以进行选择,单个事件进行监听:

java 复制代码
anima.addListener(new AnimatorListenerAdapter(){
    @Override
    public void onAnimationEnd(Animator animation){
        //结束
    }
});

AnimatorSet

AnimatoSet 可以通过 playTogether()、playSequentially()、animSet.play().with()、before()、after(),来控制多个动画的协同工作方式,从而做到对动画播放顺序的控制。

java 复制代码
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"translation",300f);
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"scaleX",1);
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"scaleY",1);
AnimatorSet set=new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1,animator2,animator3);//同时播放动画
set.start();

自定义动画

通过继承Animation类,重写其动画的方法实现。

其中一个关键方法如下:

bash 复制代码
applyTransformation(float interpolatedTime ,transformation t)
  • interpolatedTime:插值器的时间因子,取值范围为0~1 之间;
  • transformation :矩阵封装类,使用它获取矩阵对象getMatrix();

案例,模拟电视机关闭效果的动画来初步了解自定义动画。代码实现如下:

java 复制代码
/**
 * Created by aiyang on 2018/5/28.
 */
public class CustomTV extends Animation {
    private int mCenterWidth;
    private int mCenterHeight;
    private Camera camera=new Camera();
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        setDuration(2000);
        setFillAfter(false);
        setRepeatCount(3);
        setInterpolator(new AccelerateInterpolator());
        //缩放的中心位置
        mCenterWidth = width/2;
        mCenterHeight = height/2;
    }
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final Matrix matrix=t.getMatrix();
        //让一个图像纵向比例不断缩小就能实现电视机关闭的效果
        matrix.preScale(1,1-interpolatedTime,mCenterWidth,mCenterHeight);
    }
}

自定义3D动画

结合矩阵Matrix,并使用 Camera 类可以实现一个自定义的3D动画效果。

这里的Camera并非系统相机类,而是指的是android.graphics.Camera 中的 Camera 类,它封装了openGL的3D动画,从而可以非常方便的创建3D动画效果。

接上面的代码进行修改,如下:

java 复制代码
/**
 * Created by aiyang on 2018/5/28.
 */
public class CustomAnim extends Animation {
    private int mCenterWidth;
    private int mCenterHeight;
    private Camera mCamera = new Camera();
    private float mRotateY = 0.0f;
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        setDuration(3000);
        setFillAfter(true);
        setRepeatCount(3);
        setInterpolator(new BounceInterpolator());
        mCenterWidth = width / 2;
        mCenterHeight = height / 2;
    }
    //暴露接口,设置旋转角度
    public void setRotateY(float rotateY){
        mRotateY=rotateY;
    }
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final Matrix matrix=t.getMatrix();
        mCamera.save();
        //使用Camera设置旋转的角度
        mCamera.rotateY(mRotateY*interpolatedTime);
        //将旋转变换作用到Matrix上
        mCamera.getMatrix(matrix);
        mCamera.restore();
        //通过pre方法设置矩阵作用前的偏移量来改变旋转中心
        matrix.preTranslate(mCenterWidth,mCenterHeight);
        matrix.postTranslate(-mCenterWidth,-mCenterHeight);
    }
}

代码调用

java 复制代码
 CustomAnim anim = new CustomAnim();
 anim.setRotateY(10);
 textView.setText("推开门");
 textView.startAnimation(anim);

当然,根据对属性动画的知识学习,我们知道属性动画可以支持3D旋转:

即rorationX 和 rorationY :控制View围绕支点进行2D和3D旋转;

相关推荐
selt7919 小时前
Redisson之RedissonLock源码完全解析
android·java·javascript
Yao_YongChao10 小时前
Android MVI处理副作用(Side Effect)
android·mvi·mvi副作用
非凡ghost11 小时前
JRiver Media Center(媒体管理软件)
android·学习·智能手机·媒体·软件需求
席卷全城11 小时前
Android 推箱子实现(引流文章)
android
齊家治國平天下11 小时前
Android 14 系统中 Tombstone 深度分析与解决指南
android·crash·系统服务·tombstone·android 14
maycho12313 小时前
MATLAB环境下基于双向长短时记忆网络的时间序列预测探索
android
思成不止于此13 小时前
【MySQL 零基础入门】MySQL 函数精讲(二):日期函数与流程控制函数篇
android·数据库·笔记·sql·学习·mysql
brave_zhao14 小时前
达梦数据库(DM8)支持全文索引功能,但并不直接兼容 MySQL 的 FULLTEXT 索引语法
android·adb
sheji341614 小时前
【开题答辩全过程】以 基于Android的网上订餐系统为例,包含答辩的问题和答案
android
easyboot14 小时前
C#使用SqlSugar操作mysql数据库
android·sqlsugar