Android动画分为三种,逐帧动画、补间动画、属性动画,其中属性动画是Android 3.0引入的。
逐帧动画顾名思义就是按帧走的,跟Flash制作中的帧一样,具体在代码中的表现是这样的:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/chat_voice_play_right_3"
android:duration="200" />
<item
android:drawable="@drawable/chat_voice_play_right_1"
android:duration="200" />
<item
android:drawable="@drawable/chat_voice_play_right_2"
android:duration="200" />
<item
android:drawable="@drawable/chat_voice_play_right_3"
android:duration="200" />
animation-list>
oneshot表示是否只运行一次,false的情况下,如果只有start();没有stop();的情况下是不会停止的,它会逐个按顺序执行相应的图片或者其他,以达到动画的效果,现在多用于显示内容“加载中…”,例如网易云音乐在签到的时候,这是所有动画中使用最简单的一个。使用方式如下:
ImageView imageView = (ImageView) findViewById(R.id.iv_zhuzhen_voice);
imageView.setBackgroundResource(R.drawable.voice_left);//可以直接在xml里面设置background
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.start()
其实就是几张图片按顺序来回展示,达到动画的效果。
注意:逐帧动画容易引起OOM;
补间动画大体上分为四种:位移、缩放、淡入淡出、旋转,这是最简单的四种,但是可以组合使用达到高级的动画效果。
补间动画可以使用xml的形式实现(文件建立在anim文件夹下,没有需创建),也可以使用代码形式实现,主流是xml,因为简单易复用。举例:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float" //fromAlpha:起始透明度
android:toAlpha="float" //toAlpha:终止透明度
/>
<scale
android:fromXScale="float" //x轴方向的缩放起始尺寸
android:toXScale="float" //x轴方向的缩放终点尺寸
android:fromYScale="float" //y轴方向的缩放起始尺寸
android:toYScale="float" //y轴方向的缩放终点尺寸
android:pivotX="float" //缩放的X轴的坐标
android:pivotY="float" //缩放的y轴的坐标
/>
<translate
android:fromXDelta="float" //x轴方向的位移起始值
android:toXDelta="float" //x轴方向的位移终点值
android:fromYDelta="float" //y轴方向的位移起始值
android:toYDelta="float" //y轴方向的位移终点值
/>
<rotate
android:fromDegrees="float" //旋转的起始角度
android:toDegrees="float" //旋转的终止角度
android:pivotX="float" //旋转的x轴坐标
android:pivotY="float" //旋转的y轴坐标
/>
<set>
...
set>
set>
注释我就直接写在后面了,正规注释感觉理解要麻烦一些。
透明度动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(5000); //时间必须给,否则不执行
imageView_alpha.startAnimation(alphaAnimation);
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="10000">
<alpha
android:fromAlpha="100"
android:toAlpha="0" />
set>
Animation animation = AnimationUtils.loadAnimation(this,R.anim.bujian_animation_alpha);
imageView_alpha.startAnimation(animation);
缩放动画
caleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation.setDuration(5000); //时间必须给,否则不执行
imageView_scale.startAnimation(scaleAnimation);
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000">
<scale
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
set>
Animation animationScale = AnimationUtils.loadAnimation(this, R.anim.bujian_animation_scale);
imageView_scale.startAnimation(animationScale);
fromXScale和toXScale的意思是,动画开始时在X轴方向上View呈现的宽度相对于原始View的尺寸,0.0表示没有,看不见了,1.0表示原始View的宽度一致,2.0表示2倍,很好理解,fromXscale=”0.0”,toXScale=”1.0”表示从刚开始时的没有到动画结束时与原始View一样宽,Y同理。
其中最不好理解的是privotX和privotY,这个值可以取三类值:50、50%/0.5、50%p,以X轴举例,50表示以原始View的左上角为起点,向X正轴方向加50px,作为动画的中心点X轴坐标,50%/0.5表示以原始View的左上角为起点,加上自身X轴证方向宽度的50%作为动画中心点的x轴坐标,也就是整个View的一半,如果Y轴也这么写,结果就是View的中心点,正是上面gif图片的样子,从View的中心点开始缩放,而不是上下左右其他点,50%p表示以父控件为取值控件,即View的左上角为起点,加上父控件宽度的50%作为动画中心起点x轴坐标。
个人理解:缩放时有一个点是不动的,当fromXscale=“0.0”且fromYscale=”0.0”时,这个点是看不见的,pivotX和pivotY就是用来确定这个点的位置的,缩放时就是以这个点为中心点,再确定坐标方向,然后进行缩放,这个点可以在上下左右四个角上,也可以在View的坐标中心,还有可能在View的随便哪个像素上。个人理解,十分欢迎指正。
还是上效果图吧,文字有些枯燥(pivotX=” ” pivotY=” “):
50:
50%/5.0:
50%p:
借用一幅图(http://blog.csdn.net/hust_twj/article/details/78587989):
TranslateAnimation translateAnimation = new TranslateAnimation(100, 500, 0, 0);
translateAnimation.setDuration(5000); //时间必须给,否则不执行
imageView_translate.startAnimation(translateAnimation);
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000">
<translate
android:fromXDelta="100"
android:fromYDelta="0"
android:toXDelta="500"
android:toYDelta="0" />
set>
Animation animationTranslate = AnimationUtils.loadAnimation(this, R.anim.bujian_animation_translate);
imageView_translate.startAnimation(animationTranslate);
fromXDelta和toXDelta指的是动画起始位置是相对于原始View位置的左上角向X正方向移动100px得到的,Y轴同理,正值表示正轴方向,负值表示负轴方向。
RotateAnimation rotateAnimation = new RotateAnimation(0, -90, 0, 0);//我使用代码实现时效果有问题,所以还是建议使用xml实现。
rotateAnimation.setDuration(4000); //时间必须给,否则不执行
imageView_rotate.startAnimation(rotateAnimation);
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000">
<rotate
android:fromDegrees="0"
android:pivotX="0%"
android:pivotY="0%"
android:toDegrees="-90" />
set>
Animation animationRotate = AnimationUtils.loadAnimation(this, R.anim.bujian_aniamtion_rotate);
imageView_rotate.startAnimation(animationRotate);
依旧是个人理解:pivotX和pivotY属性只有在缩放动画和旋转动画里看到,我认为这是在定位一个点,不管是缩放还是旋转都要有一个参考点或中心点,定位了之后才是怎么转,怎么缩,往哪个方向转和缩等等。
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<set
android:duration="2000"
android:startOffset="2000">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5" />
set>
<set
android:duration="2000"
android:startOffset="4000">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="500"
android:toYDelta="0" />
set>
set>
按顺序:透明度动画—>缩放动画—>位移动画,因为有startOffset属性,不指定这个属性就是一起执行,比如:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.0"
android:toYScale="0.0" />
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="500"
android:toYDelta="0" />
<rotate
android:fromDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-360" />
set>
补充:在xml中除了常见的duration属性以外,还有其他属性
补间动画能实现很多效果,但是局限性也大,1.它只有这四种动画,即使可以组合有些效果也达不到。2.它是依托于View的,不能依托于非View对象。3.它并没有改变View的属性,比如位移,虽然移动了但是并没有改变它的点击区域,在位移后的位置点击是没有效果的,只有点击原始位置才可以。所以实际开发中还是使用属性动画的比较多。
参考文章(感谢):
https://www.jianshu.com/p/c0ad225a30c0
http://blog.csdn.net/hust_twj/article/details/78587989