文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

我的Android开发之旅(二):Android三种动画效果的浅入之View动画

2022-06-06 13:56

关注

我的Android开发之旅(二):Android三种动画效果的浅入之View动画前言View动画Animation类1. 平移动画2. 缩放动画3. 旋转动画4. 透明动画AnimationSet 动画集合自定义View动画补充 前言

在Android中动画可以分为3种:View动画、帧动画和属性动画。View动画从名字就可以大致知道,View动画是对View做图形变换(平移、缩放、旋转、透明度)从而产生动画效果,并且View动画支持自定义。帧动画是通过顺序播放一系列的图片从而产生的动画效果。属性动画是在API11(Android3.0)引进的动画效果,它是通过动态地改变对象的属性从而达到动画效果。

View动画

View动画的作用对象是View,它支持4种动画效果,分别是平移、缩放、旋转、透明度动画。View动画的四种动画效果对应着Animation类的四个子类:
TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation。这4种动画即可以通过XML来定义,也能通过Java代码来动态创建。对于View动画来说,推荐使用XML来定义,可读性高。

名称 标签 子类 效果
平移动画 TranslateAnimation 移动View
缩放动画 ScaleAnimation 放大或缩小View
旋转动画 RotateAnimation 旋转View
透明度动画 AlphaAnimation 改变View的透明度

在这里插入图片描述

Animation类

在实现动画效果之前,先讲一下Animation类,它是一个抽象类,可以应用于视图、表面或其他对象的动画。
Animation一些常用的方法:

Animation类常用的方法 作用
reset() 重置Animation的初始化
cancel() 取消Animation动画
start() 开始Animation动画
setAnimationListener() 给当前Animation设置动画监听
hasStarted() 判断当前Animation是否开始
hasEnded() 判断当前Animation是否结束

View类对Animation的常用方法:

方法 作用
startAnimation(Animation animation) 对当前View开始设置的Animation动画
clearAnimation() 取消当View在执行的Animation动画

Animation常用的属性:

xml属性 java方法 作用
android:duration setDuration(long) 动画持续时间,毫秒为单位
android:fillAfter setFillAfter(boolean) 控件动画结束时是否保持动画最后的状态
android:fillBefore setDuration(long) 动画持续时间,毫秒为单位
android:duration setFillBefore(boolean) 控件动画结束时是否还原到开始动画前的状态
android:ShareInterpolator setInterpolator(Interpolator) 设定插值器(指定的动画效果,譬如回弹等)
android:startOffset setStartOffset(long) 调用start函数之后等待开始运行的时间,单位为毫秒

上面的表格中涉及到 插值器 。那么什么是插值器呢?官方的注释解释道:插值器定义了动画的变化率。这允许基本的动画效果(透明,缩放,平移,旋转)被加速,减速,重复等。

接着我们打开 activity_main.xml 文件,添加 Button 和 TextView。 Button 用来开启动画效果, TextView 用来显示动画效果。


        

布局设置好之后我们再到 MainActivity.java 文件中给 btnTranslation 添加点击事件,实现向下平移的效果。

这里我推荐大家用 ButterKnife 通过注解的方式绑定 View 就不需要 findByid() 了,配合插件(butterknife-zelezny)控件的绑定和点击事件代码一键生成,提高你的工作效率,美滋滋。


public class MainActivity extends AppCompatActivity {
    @BindView(R.id.tvAnimation)
    TextView tvAnimation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }
    @OnClick(R.id.btnTranslation)
    public void onViewClicked(View view) {
        // 方法一:通过xml方式实现动画效果
        Animation animation = null;
        switch (view.getId()) {
            case R.id.btnTranslation:
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
                break;
            default:
        }
        tvAnimation.startAnimation(animation);
//        // 方法二:通过代码动态的实现动画效果
//        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, 800);
//        translateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(translateAnimation);
    }
}

动画效果:
向下平移效果

2. 缩放动画

缩放的动画效果用到了 ScaleAnimation 类,ScaleAnimation属性如下:

xml属性 java方法 作用
android:fromXScale ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) X轴开始的缩放比例,1.0表示无变化
android:toXScale ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) X轴结束的缩放比例
android:fromYScale ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) Y轴开始的缩放比例,1.0表示无变化
android:toYScale ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) Y轴结束的缩放比例
android:pivotX ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) X轴的缩放起始点(当对象改变大小时,这个点保持不变)这里可以是数值,百分比,百分比p
android:pivotY ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) Y轴的缩放起始点(当对象改变大小时,这个点保持不变)这里可以是数值,百分比,百分比p

数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点。如果不太明白,可以自己动手试试,看看效果。

缩放动画效果的创建也是一样,这里我就不详细说明了,创建 scale_anim.xml 和 修改 activity_main.xml、MainActivity.java ,代码如下:

scale_anim.xml 文件


activity_main.xml 文件


        

MainActivity.java 文件


public class MainActivity extends AppCompatActivity {
    @BindView(R.id.tvAnimation)
    TextView tvAnimation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }
    @OnClick({R.id.btnTranslation, R.id.btnScale})
    public void onViewClicked(View view) {
        // 方法一:通过xml方式实现动画效果
        Animation animation = null;
        switch (view.getId()) {
            case R.id.btnTranslation:
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
                break;
            case R.id.btnScale:
                animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
            default:
        }
        tvAnimation.startAnimation(animation);
        // 方法二:通过代码动态的实现动画效果
//        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, 800);
//        translateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(translateAnimation);
//        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        scaleAnimation.setDuration(2000);
//        tvAnimation.startAnimation(scaleAnimation);
    }
}

动画效果:
缩放动画效果

3. 旋转动画

旋转的动画效果用到了 RotateAnimation 类,RotateAnimation属性如下:

xml属性 java方法 作用
android:fromDegrees RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) 动画开始时的角度,正数代表顺时针,负数代表逆时针
android:toDegrees RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) 动画结束时的角度,正数代表顺时针,负数代表逆时针
android:pivotX RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) X轴的旋转起始点,这里可以是数值,百分比,百分比p
android:pivotY RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) Y轴的旋转起始点,这里可以是数值,百分比,百分比p

rotate_anim.xml 文件


activity_main.xml 文件


        

MainActivity.java 文件

@OnClick({R.id.btnTranslation, R.id.btnScale, R.id.btnRotate})
    public void onViewClicked(View view) {
        // 方法一:通过xml方式实现动画效果
        Animation animation = null;
        switch (view.getId()) {
            case R.id.btnTranslation:
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
                break;
            case R.id.btnScale:
                animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
                break;
            case R.id.btnRotate:
                animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
                break;
            default:
        }
        tvAnimation.startAnimation(animation);
        // 方法二:通过代码动态的实现动画效果
//        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, 800);
//        translateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(translateAnimation);
//        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        scaleAnimation.setDuration(2000);
//        tvAnimation.startAnimation(scaleAnimation);
//        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        rotateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(rotateAnimation);
    }

动画效果:
旋转动画效果

4. 透明动画

透明的动画效果用到了 AlphaAnimation 类,AlphaAnimation属性如下:

xml属性 java方法 作用
android:fromAlpha AlphaAnimation(float fromAlpha, float toAlpha) 动画开始时的透明度(范围:0.0-1.0,1.0不透明,0.0全透明)
android:toAlpha AlphaAnimation(float fromAlpha, float toAlpha) 动画结束时的透明度(范围:0.0-1.0,1.0不透明,0.0全透明)

alpha_anim.xml 文件


activity_main.xml 文件


        

MainActivity.java 文件

@OnClick({R.id.btnTranslation, R.id.btnScale, R.id.btnRotate, R.id.btnAlpha})
    public void onViewClicked(View view) {
        // 方法一:通过xml方式实现动画效果
        Animation animation = null;
        switch (view.getId()) {
            case R.id.btnTranslation:
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
                break;
            case R.id.btnScale:
                animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
                break;
            case R.id.btnRotate:
                animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
                break;
            case R.id.btnAlpha:
                animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
                break;
            default:
        }
        tvAnimation.startAnimation(animation);
        // 方法二:通过代码动态的实现动画效果
//        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, 800);
//        translateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(translateAnimation);
//        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        scaleAnimation.setDuration(2000);
//        tvAnimation.startAnimation(scaleAnimation);
//        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        rotateAnimation.setDuration(2000);
//        tvAnimation.startAnimation(rotateAnimation);
//        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
//        alphaAnimation.setDuration(2000);
//        tvAnimation.setAnimation(alphaAnimation);
    }

动画效果:
透明动画效果

AnimationSet 动画集合

相信大家对4个动画效果的使用有初步的了解了,那么现在你可能会问:如果我想把4是个动画效果集成在一起呢?应该如何实现? 如果你有细心观察的话,会发现我们在创建完一个 animation resource file的xml文件之后打开会发现有个 标签,表示动画集合,对应 AnimationSet类,有多个动画构成。

AnimationSet类继承自Animation类,是上面四种的组合容器管理类,没有自己特有的属性,他的属性继承自Animation类。当我们对set标签使用Animation类的属性时会对该标签下的所有子控件都产生影响。譬如我们在set标签下加入duration=“1000”,子控件的duration属性会失效。

那么我们现在把刚刚学到的4个动画效果集成在一起,看看会是什么样子的。

新建一个 animation resource file 的xml文件 ,命名为 set_anim.xml,这里我给动画集合时间设置了4秒,还添加了一个开始速率较快,后面减速的插值器:

    
    
    
    
在界面中添加一个控件,用于控制动画效果:

    
给btnSet添加点击事件:
 @OnClick({R.id.btnTranslation, R.id.btnScale, R.id.btnRotate, R.id.btnAlpha, R.id.btnSet})
    public void onViewClicked(View view) {
        // 方法一:通过xml方式实现动画效果
        Animation animation = null;
        switch (view.getId()) {
            case R.id.btnTranslation:
                animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
                break;
            case R.id.btnScale:
                animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
                break;
            case R.id.btnRotate:
                animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
                break;
            case R.id.btnAlpha:
                animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
                break;
            case R.id.btnSet:
                animation = AnimationUtils.loadAnimation(this, R.anim.set_anim);
            default:
        }
        tvAnimation.startAnimation(animation);
        // 方法二:通过代码动态的实现动画效果
//        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, 800);
//        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, tvAnimation.getWidth() / 2, tvAnimation.getHeight() / 2);
//        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
//        AnimationSet animationSet = new AnimationSet(true);
//        animationSet.setDuration(4000);
//        animationSet.setInterpolator(new DecelerateInterpolator());
//        animationSet.addAnimation(translateAnimation);
//        animationSet.addAnimation(scaleAnimation);
//        animationSet.addAnimation(rotateAnimation);
//        animationSet.addAnimation(alphaAnimation);
//        tvAnimation.startAnimation(animationSet);
    }
动画效果:
动画集合效果 自定义View动画

系统提供的4种动画效果已经可以满足绝大部分的动画效果了,但有特殊要求,我们也是可以自定义View动画效果的。那么如何自定义View动画效果呢?我们从前面的Animation类的介绍了解到,它是一个抽象类,我们只需要继承它,并覆写它的initialize和applyTransformation方法。在initialize中做初始化工作,在applyTransformation中做相应的矩阵变换(需要用到Camera来简化矩阵的变化过程),需要用到数学知识。这里参考了 Android 的 apidemo 中自定义View动画 Rotate3dAnimation。Rotate3dAnimation 可以围绕Y轴旋转并且同时沿着Z轴平移从而实现一种类似3D的效果。具体的代码和使用可以参考这篇文章:翻牌(翻转)动画-Rotate3dAnimation的应用

补充

在动画效果执行完成之后,并没有改变View的位置。如,我左上角有一个Button,我把往下平移,并保持动画结束后的状态,此时你再点击左上角Button位置时,依旧能响应Button的点击事件。而你点击平移后的Button是没有任何反应的。

在进行动画的时候,尽量使用dp,因为px会导致适配问题。

项目代码下载地址:码云


作者:梁大侠0206


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯