Android的动画就可以分为3种:
- View动画
View Animation
- 帧动画
Drawable Animation
- 属性动画
Property Animation
1.View动画
View动画的作用对象是View。View动画的View移动只是视觉效果,并不能真正的改变位置。
View动画的种类
| 种类 |
标签 |
子类 |
效果 |
| 平移动画 |
<translate> |
TranslateAnimation |
平移View |
| 缩放动画 |
<scale> |
ScaleAnimation |
放大或者缩小View |
| 旋转动画 |
<rotate> |
RotateAnimation |
旋转View |
| 透明度动画 |
<alpha> |
AlphaAnimation |
View的透明度变化 |
使用View动画
要使用View动画,需要先创建动画的XML文件,这个文件的路径为res/anim/animateFile.xml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="" android:shareInterpolator="[true | false]" android:fillAfter="true" android:duration='integar'> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float"/> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float"/> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotY="float" android:pivotX="float"/> <alpha android:fromAlpha="float" android:toAlpha="float"/>
</set>
|
View动画既可以是单个动画,也可以由一系列动画组成。
<set>:表示动画集合,对应AnimationSet,可以包含若干个动画,并且内部也可以嵌套其他动画集合。
android:interpolator:表示动画集合所采用的插值器,插值器会影响到动画的速度。
android:shareInterpolator:是否共享插值器。如果不指定,子动画就需要单独指定插值器或者使用默认值。
android:fillAfter:表示动画结束时是否保持动画结束的状态。false回到动画初始样式
android:integar:表示动画持续时长
<translate>:表示平移动画,对应TranslateAnimation
android:fromXDelta:动画起始时X坐标上的位置。
android:toXDelta:动画结束时X坐标上的位置。
android:fromYDelta:动画起始时Y坐标上的位置。
android:toYDelta:动画结束时Y坐标上的位置。
以上4个属性的取值可能为数值,百分数,百分数P,他们的含义有所区别:
数值: 50 –> 以View左上角为原点,向正方向偏移50px
百分数 50% –> 以View左上角为原点,向正方向偏移View宽/高的50%
百分数P 50%P -> 以View左上角为原点,向正方向偏移父布局(parent)宽/高的50%;
<scale>:表示缩放动画,对应ScaleAnimation
android:fromXScale动画起始时水平方向伸缩值。
android:toXScale:动画结束时水平方向伸缩值。
android:fromYScale:动画起始时竖直方向伸缩值。
android:toYScale:动画结束时水平方向伸缩值。
以上4个属性的取值有不同的含义
值为0.0 缩放比为0 代表缩放到原来的0 即消失
值<1.0 缩放比小于1 代表缩小
值为1.0 缩放比等于1 代表与原来相同
值>1.0 缩放比大于1 代表放大
android:pivotX:缩放轴点的X坐标。
android:pivotY:缩放轴点的Y坐标。
以上两个属性表示 ,缩放的起始坐标,取值为%,默认View的中心点,即50%,50%。举个例子:如果pivotX和pivotY设置为0,即为左上角坐标,缩放时就是以左上角为原点向外向内。
<rotate>:表示旋转动画,对应RotateAnimation
android:fromDegrees:动画起始时旋转的角度 。
android:toDegrees:动画结束时旋转的角度。
以上两个属性共同确定旋转方向,原则是:当角度为负数时表示逆时针旋转,反之。
故共存在以下四种情况:
- from=负数 -> to=正数:表示顺时针旋转
- from=负数 ->to =负数:表示逆时针旋转
- from=正数 ->to =正数:表示顺时针旋转
- from=正数 ->to=负数:表示逆时针旋转
android:pivotX:旋转轴点的X坐标。
android:pivotY:旋转轴点的Y坐标。
<alpha>:表示透明度动画,对应AlphaAnimation
android:fromAlpha:动画起始时透明度。
android:toAlpha动画结束时透明度。
以上两个属性取值范围为 0~1
值<=0 代表完全透明
值>=1 代表完全不透明
应用代码
通过XML文件构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true" > <translate android:duration="2000" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="100%" android:toYDelta="100%"> /> <scale android:duration="2000" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:toXScale="0.5" android:toYScale="0.5" /> <rotate android:duration="2000" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"/> <alpha android:duration="2000" android:fromAlpha="1.0" android:toAlpha="0"/> </set>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Animation animation = AnimationUtils.loadAnimation(this,R.anim.animationet); view.startAnimation(animation); animation.setAnimationListener(new AnimationListener(){ void onAnimationStart(Animation animation){ } void onAnimationEnd(Animation animation){ } void onAnimationRepeat(Animation animation){ } })
|
通过Java构建
1 2 3 4 5 6 7
| AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); alphaAnimation.setDuration(2000);
AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(alphaAnimation);
view.startAnimation(animationSet);
|
自定义View动画
自定义View动画是为了 实现系统提供的无法满足的动画情况,例如3D翻转效果,无法简单组合就能实现,就需要用到自定义View动画。
实现步骤:继承Animation -> 重写initialize()以及applyTransformation()方法
inltialize():初始化工作
allpyTransformation():进行相应的矩阵变换
自定义View动画实例
TODO
View动画特殊使用场景
1. LayoutAnimation
作用于ViewGroup,为ViewGroup指定一个动画,当它的子元素出场时都会具有这样的效果。
1 2 3 4
| <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="" android:animationOrder="" android:animation="" />
|
android:delay:表示子元素开始动画的延迟时间。
比如,设置子元素入场动画的周期为 300ms,delay设置为0.5意味着,每个子元素都需要延迟150ms播放动画
android:animationOrder :表示子元素动画的顺序
- normal 正序显示,按照排列顺序播放
- random 随机显示
- reverse 逆序显示
android:animation:表示设置的子元素动画
应用代码
XML定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| // anim_layout.xml <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animation="@anim/anim_layout_item" android:delay="0.5" android:animationOrder="normal"> </layoutAnimation>
//anim_layout_item.xml <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:shareInterpolator="true" android:interpolator="@android:anim/accelerate_interpolator"> <alpha android:fromAlpha="0" android:toAlpha="1" /> <scale android:fromXScale="1" android:toXScale="0" /> </set>
<ListView android:layoutAnimation ="@anim/anim_layout" />
|
Java代码生成
1 2 3 4 5
| Animation animation = AnimationUtils.loadLayoutAnimation(this, R.anim.anim_item); LayoutAnimationController controller = new LayoutAnimationController(animation); controller.setDelay(0.5); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); listView.setLayoutAnimation(controller);
|
2.Activity切换效果
Activity有默认的切换效果,是由系统自己定义的。需要自定义切换效果就需要用到oberridePendingTransition(int inAnim,int outAnim)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // enter_anim.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> <scale android:fromXScale="2.0" android:toXScale="1.0" android:fromYScale="2.0" android:toYScale="1.0" android:pivotX="50%p" android:pivotY="50%p" android:duration="@android:integer/config_mediumAnimTime" /> </set>
//exit_anim.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator" android:zAdjustment="top"> <scale android:fromXScale="1.0" android:toXScale=".5" android:fromYScale="1.0" android:toYScale=".5" android:pivotX="50%p" android:pivotY="50%p" android:duration="@android:integer/config_mediumAnimTime" /> <alpha android:fromAlpha="1.0" android:toAlpha="0" android:duration="@android:integer/config_mediumAnimTime"/> </set>
|
1 2 3 4 5 6
| Intent intent =new Intent(this,AnimActivity.class); startActivityIntent(intent); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
finish(); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
|
该方法必须在startActivity()或者finish()之后调用才生效。
2.帧动画
帧动画是顺序播放一组预先定义好的图片,对应AnimationDrawable
1 2 3 4
| <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="[true | false]"> <item android:drawable="" android:duration="intreger"/> </animation-list>
|
android:oneshot:表示是否播放一次
应用代码
XML方式
1 2 3 4 5 6 7 8
| // animationlist.xml <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/bg1" android:duration="500"/> <item android:drawable="@drawable/bg2" android:duration="500"/> <item android:drawable="@drawable/bg3" android:duration="500"/> <item android:drawable="@drawable/bg4" android:duration="500"/> </animation-list>
|
1 2 3
| view.setBackgroundResource(R.drawable.animationlist); AnimationDrawable animationDrawable = (AnimationDrawable)mView.getBackground(); animationDrawable.start();
|
Java生成
1 2 3 4 5 6 7 8
| AnimationDrawable ad = new AnimationDrawable(); for (int i = 0; i < 4; i++) { Drawable drawable = getResources().getDrawable(getResources().getIdentifier("bg" + i, "drawable", getPackageName())); ad.addFrame(drawable, 500); } ad.setOneShot(false); mView.setBackgroundResource(ad); ad.start();
|
使用帧动画时要注意不能使用尺寸过大的图片。否则容易造成OOM错误
优化内存占用
由于图片全部是从xml中读取的,一定要全部读取下来动画才可以开始,因为要不断地替换图片去实现动画效果。一次性取出所有图片,就容易导致OOM
优化思路:一次只取一个图片,开启一个线程去取下一张,达到一致的效果。
3.属性动画
Android动画-属性动画