Android动画系列——View动画和帧动画

Android开发中,常用的动画有三种,View动画,帧动画和属性动画。

View动画

View动画也被称为TweenAnimation,是在视图上执行补间动画,它作用于视图整体。补间动画指的是只要指定动画开始和结束时刻的“关键帧”,而动画变化过程的“中间帧”由系统计算并补齐。无论动画如何改变视图的显示区域,视图原来的边界也不会自动调整(缩放)来适应视图动画的显示区域。那么就可以这样理解:视图通过ScaleAnimation或者TranslateAnimation动画,使显示区域超过了视图原有的边界,视图不会被剪裁。与之相反的是,当视图的动画超过父容器的边界时,显示区域将被剪裁。
系统提供的View动画有且只有4种:TranslateAnimation(平移动画)、AlphaAnimation(透明度动画)、ScaleAnimation(缩放动画)、Rotation(旋转动画)。他们都是以Animation类的派生类。具体的相关类的继承图如下:


Android动画系列——View动画和帧动画_第1张图片
Animation的派生类

AnimationSet是动画集合类,可以将多个不同的XxxAnimation组合,形成一组复杂效果的View动画。
使用View动画主要有两种方式,xml定义和代码定义:
先看看xml定义,首先在res/anim目录下定义一个xml文件


    

然后通过AnimationUtils加载xml中的动画,生成Animation对象

TranslateAnimation translateAnimation = AnimationUtils.loadAnimation(context,R.anim.anim_translate);
intentBtn.startAnimation(translateAnimation);

最后调用视图的startAnimation方法给视图设置动画并开始。
再来看看在代码中定义:

TranslateAnimation translateAnimation = new TranslateAnimation(0f, 0f, 0f, 200f);
translateAnimation.setDuration(1000);//动画的持续时间,单位毫秒
translateAnimation.setFillAfter(true);//参数为true表示动画结束后View停留在结束位置
intentBtn.startAnimation(translateAnimation);

上面的代码是简单的Animation动画的使用方式,其中值得一提的是,setFillAfter(true)方法,参数为true,表示动画结束后,视图停留在完成时的位置;参数为false(默认),表示动画结束后,视图还原到起始位置。
我们还可以给Animation设置监听事件,监听动画的开始和结束

translateAnimation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        //动画开始时调用
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                      //动画结束时调用
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                      //动画重复播放时调用
                    }
                });
View动画的两个常用的特殊场景
  • ViewGroup子视图的布局动画(LayoutAnimation)。以ListView为例:
//然后在代码中,给ListView设置动画(LayoutAnimation)
LayoutAnimationController lac=new LayoutAnimationController(AnimationUtils.loadAnimation(this, R.anim.zoom_in));
lac.setDelay(0.5f);
lac.setOrder(LayoutAnimationController.ORDER_RANDOM);
mListView.setLayoutAnimation(lac);

//也可以layout文件中给ListView设置layoutAnimation属性


layoutAnimation虽然是API 1中就已经引入,但只能在ViewGroup初次创建时才能使用指定动画。容器创建以后,再往ViewGroup里加Item就不会再有动画。在API 11之后,Android为了支持ViewGroup类控件,在添加和移除其中控件时自动添加动画,为我们提供了一个非常简单的属性:android:animateLayoutChanges=“true”,所有派生自ViewGroup的控件都具有此属性,只要在XML中添加上这个属性,就能实现添加/删除其中控件时,带有默认动画了。但是这个属性设置后,只能使用默认的动画,不支持自定义动画。同时在API 11时引入的LayoutTransaction也能起到LayoutAnimation+animateLayoutChanges效果,并且能够设置自定义动画。它的使用涉及到属性动画,相对LayoutAnimation的使用更复杂,以后再提。

  • 通过补间动画(Tween animation)为Activity自定义切换动画
    Android系统为Activity设置了默认的切换动画,这个动画我们是可以进行自定义的。通过调用Activity类的overridePendingTransition(int enterAnim, int exitAnim)方法可以实现自定义Activity的切换动画,注意这个方法必须在startActivity和finish调用之后被调用,否者没有效果。
View动画的缺点

它只是改变了视图的显示,但没有改变视图的响应区域。也就是说,比如你用ScaleAnimation将视图放大或缩小,其实视图的点击响应区域还是动画开始前的位置;或者用TranslateAnimation将视图平移到另一个位置,点击响应区域还是在动画开始前的位置,而动画结束时视图所在的区域没有点击响应。

帧动画

帧动画也就是Drawable动画,是用来逐帧显示定义好的一组图片或者Drawable资源。效果类似于范灯片,一张张地切换图片。对应于AnimationDrawable类。实际的开发中,帧动画使用的场景相对较少。
典型的用法如下:
首先在res/drawable目录下通过xml定义一个帧动画(AnimationDrawable)



    
    
    
    
    
    

标签表示一组帧动画,oneshot属性为true,表示动画只播放一次,否则就会重复播放。每一个item对应每一帧的图片。duration属性表示每一帧显示的时间。
接下来将定义好的AnimationDrawable设置为View的背景或者ImageView的图像

AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_list);
image.setImageDrawable(animationDrawable);
animationDrawable.start();

以上是通过xml的方式定义帧动画(AnimationDrawable),当然也可以通过代码来定义

AnimationDrawable animationDrawable = new AnimationDrawable();
animationDrawable.addFrame(getResources().getDrawable(R.drawable.first_pic), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.second_pic), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.third_pic), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.fourth_pic), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.fifth_pic), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.sixth_pic), 1000);
animationDrawable.setOneShot(true);
image.setImageDrawable(animationDrawable);
animationDrawable.start();

有一点需要强调的是:启动animationDrawable.start()不能在Activity的onCreate和onStart中调用,因为在onCreate和onStart中AnimationDrawable还没有完全的与ImageView绑定,在onCreate和onStart中启动动画,就只能看到第一张图片。解决的办法是确保Activity在Resume状态下调用animationDrawable.start()。
帧动画的缺陷是不能添加监听事件。

本文参考:
https://www.jianshu.com/p/b117c974deaf
https://www.jianshu.com/p/5d811aaf4541
http://wiki.jikexueyuan.com/project/android-animation/12.html

你可能感兴趣的:(Android动画系列——View动画和帧动画)