动画分类:
曾被问到Android中有几种动画,这个问题也好难回答。Android3.0之前有2种,3.0后有3种。FrameAnimation(逐帧动画):将多张图片组合起来进行播放,类似于早期电影的工作原理,很多App的loading是采用这种方式。
如果图片过多过大就会导致OOM
TweenAnimation(补间动画):是对某个View进行一系列的动画的操作,包括淡入淡出(Alpha),缩放(Scale),平移(Translate),旋转(Rotate)四种模式。
PropertyAnimation(属性动画):属性动画不再仅仅是一种视觉效果了,而是一种不断地对值进行操作的机制,并将值赋到指定对象的指定属性上,可以是任意对象的任意属性。
FrameAnimation(逐帧动画):
1. 新建文件夹:res/drawable/animation_test.xml,例如1s闪烁一次:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_launcher" android:duration="1000"/>
<item android:drawable="@mipmap/test" android:duration="1000"/>
</animation-list>
2. 调用:
bt.setBackgroundResource(R.drawable.frame_animation);
AnimationDrawable animationDrawable = (AnimationDrawable) bt.getBackground();
animationDrawable.start();
3. 帧动画尽量避免使用尺寸较大的图片。
TweenAnimation(补间动画):
一、XML文件的方式:
1. 新建文件 res/anim/filename.xml,例如:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="false">
<alpha
android:duration="2000"
android:fromAlpha="1"
android:toAlpha="0.1"/>
<translate
android:duration="1000"
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:toYDelta="100"/>
</set>
2. 调用:
case R.id.bt_test_animation:
Animation aplha = AnimationUtils.loadAnimation(this, R.anim.animation_test);
img_animation.startAnimation(aplha);
break;
二、通过代码来应用动画:
AnimationSet set = new AnimationSet(true);//true表示集合中的动画是否共享同一个插值器
TranslateAnimation translateAnimation = new TranslateAnimation(0f , 100f,0f , 100f);
AlphaAnimation alphaAnimation = new AlphaAnimation(1f , 0.1f);
set.setDuration(2000);
set.setFillAfter(true);
set.addAnimation(translateAnimation);
set.addAnimation(alphaAnimation);
img_animation.startAnimation(set);
使用 layoutAnimation 实现listview的item的挨个动画
1. 新建文件 res/anim/filename.xml,例如:
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5" //延迟加载(时间为动画时间的0.5倍)
android:animationOrder="normal" //normal顺序加载、reverse倒序、random随机
android:animation="@anim/animation_test"/> //指定动画文件
方式一: xml方式为listview添加动画属性:
<ListView
android:id="@+id/img_animation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation"/>
方式二:代码控制:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_test);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
lv_animation.setLayoutAnimation(controller);
lv_animation.setAdapter(adapter);
通过动画来控制activity的切换效果:
在startActivity(intent) 或者 finish()后面调用overridePendingTransition(int enter_anim , int exit_anim)才能生效;
参数说明:
enter_anim:打开activity时,所需的动画资源id
exit_anim:暂停activity时,所需的动画资源id
属性动画:
比较常用的几个类: ObjectAnimator ---> ValueAnimator (动画类) , AnimatorSet 动画集合原理:属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据外界传递的该属性的初始值和最终值,以动画的效果多次去调用set方法,每次传递
给set方法的值都不一样,确切的说随着时间的推移,所传递的值越来越接近最终值。三种解决办法:
1. 给你的对象添加get和set方法,如果有权限的话(往往不可行)
2. 用一个类来包装原始的对象,间接的为其提供get和set方法(很有用的方法)
3. 采用ValueAnimator,监听动画的过程实现属性的改变
一、代码动态添加属性动画:
1. 例如沿竖直方向移动:
ObjectAnimator translationY = ObjectAnimator.ofFloat(lv_animation, "translationY", bt_animation.getHeight());
translationY.setDuration(2000);
translationY.setRepeatCount(ValueAnimator.INFINITE);//默认是0, -1表示无限循环
translationY.setRepeatMode(ValueAnimator.REVERSE);//reverse逆向
translationY.start();
2. Y轴移动的同时X轴也移动:
AnimatorSet set = new AnimatorSet();
//playTogether同时执行,playSequentially先后按顺序执行
set.playTogether(
ObjectAnimator.ofFloat(lv_animation, "translationY", bt_animation.getHeight()),
ObjectAnimator.ofFloat(lv_animation, "translationX", bt_animation.getHeight())
);
set.setDuration(2000);
set.start();
二、通过XML的方式来实现:
新建文件 res/animator/filename.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together"> //表示是同时执行还是先后执行
<objectAnimator
android:propertyName="" //属性的名称
android:duration=""
android:valueFrom=""
android:valueTo=""
android:startOffset="" //延迟时间
android:repeatCount="" //重复次数:默认是0, -1表示无限循环
android:repeatMode="" //重复的模式:reverse逆向
android:valueType=""/> //属性的类型intType、floatType可选,如果是颜色,则不需要指定这个valueType
</set>
代码引用这个xml文件:
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.animator_test);
animator.setTarget(lv_animation);
animator.start();
实现非匀速的动画:
TimeInterpolator时间插值器(根据时间流逝的百分比来计算出当前属性值改变的百分比):
LinearInterpolator: 线性插值器,匀速动画
AccelerateDecelerateInterpolator: 加速减速插值器,动画两头慢中间快
DecelerateInterpolator: 减速插值器,动画越来越慢
TypeEvaluator估值器(根据当前属性改变的百分比来计算改变后的属性值):
IntEvaluator: 针对整形属性
FloatEvaluator: 针对浮点型属性
ArgbEvaluator: 针对Color属性
属性动画监听器:
AnimatorListener: 监听动画的开始、结束、取消、重复播放AnimatorUpdateListener: 监听整个动画过程,每播放一帧都会触发
使用动画要注意的问题:
1. OOM问题:
这个问题注意出现在帧动画中,当图片较多且较大的时候就极易出现OOM
2. 内存泄露:
在属性动画中有一类无限循环的动画,这类动画需要在Activity退出的时候即使停止,否则将导致Activity无法释放从而造成内存泄露,通过验证
发现View动画(帧动画、补间动画)并不存在此问题
3. 兼容问题:
属性动画是3.0 之后出现的,可以添加依赖包
4. View动画的问题:
View动画是对View的影像做动画,并不是真正的改变View的状态,因此有时候会出现动画完成后View无法隐藏的情况,及setVisibility(View.GONE)失效了,
用view.clearAnimation()清除view动画及可解决此问题
5. 不要使用px:
尽量使用dp,使用px会导致在不同的设备上有不同的效果
6. 动画元素的交互(焦点问题):
android3.0 之后出现了属性动画,属性动画的单击事件触发位置为移动后的位置,但是View动画仍然在原位置。