1.AnimationListener:监听Animation的运行过程
eg
AnimationSet as = new AnimationSet(true);
RotateAnimation rl = new RotateAnamation(
0
,-
720
,Animation.RELATIVE_TO_PARENT,
0
.5f,Animation.RELATIVE_TO_PARENT,
0
.5f);
r.setDuration(3000);
rl.setAnimationListener(new AnimationListener(){
public void onAnimationStart(Animation){
}
public void onAnimationEnd(){}
public void onAnimationRepeat(){}
})
as.addAnimation(rl);
iv.startAnimation(as);
2.自定义View:派生一种新的动画只需要继承Animation这个抽象类,然后重写它的initialize和applyTranformation,在initialize方法做一些初始化操作,在applyTransformtion进行相应的矩阵变化,应为View的动画的过程主要是矩阵的变换过程
3.帧动画:顺序播放一组预定义好的图片,系统提供了另外一个类AnimationDrawable来使用帧动画,帧动画使用比较简单,但是比较容易OOM,所以在使用帧动画时尽量避免使用较大尺寸的图片。
4.LayoutAnimation:作用于ViewGroup,为ViewGroup指定动画。
eg listView每个Item瀑布进入
<LayoutAnimation
xmlns:android = "http://schemas.android.com/apk/res/android"
android:delay = "0.5" //元素开始的时间延迟
android:animationOrder = "normal" //元素动画的顺序 normal顺序显示 reverse逆向显示,random随机播放
android:animation="@anim/anim_item"/> //为元素指定具体的入场动画
<ser xmlns:android = "http://schemas.android.com/apk/res/android"
android:duration = "300"
android:interpolator = "@android:anim/accelerate_interpolator"
android:shareInterpolator = "true">
<alpha
android:formAlpha = "0.0"
android:toAlpha = "1.0">
<translate
android:fromXDelta = "500"
android:toXDelta = "0"/
</set>
<ListView
android:id = "@+id/list"
android:layout_width = "match_parent"
android:layout_heigth = "match_parent"
android:layoutAnimation = "@anim/anim_layout"
/>
用代码设置的方法
ListView listView = (ListView
)layout.findViewById(R.id.list);
Animation animation = AnimationUtils.loadAnimation(R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setLayoutAnimation(controller);
5.Activity的切换效果
overridePendingTransition(int enterAnim,int exitAnim),这个方法必须在startActivity(Intent)或者finish()之后调用才能生效
eg
Intent intent = new Intent(this,TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
@override
public void finish(){
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
6.属性动画
属性动画可以对任意对象进行动画而不仅仅是View,动画默认时间间隔300ms,默认帧率10ms/帧
设置的属性的意义 android: startOffset 表示动画的延迟时间,当动画开始后,需要延迟多少毫秒才会真正播放此动画
android:propertyName 表示属性动画的作用对象的属性名称,如果指定的属性名称表示的是颜色,则不需指定android:valueTyoe,系统会自动对颜色类型的属性处理。
eg
AniamtionSet set = AnimetionInflate.loadAnimator(mContext,R.anim.property);
set.setTarget(set);
set.start();
在实际开发中建议采用代码来实现属性动画因为通过代码来实现比较简单,重要的是很多时候一个属性的起始值无法提前确定,比如一个Button从屏幕左边移动到屏幕的右边,由于我们无法提前知道屏幕的宽度,因此无法将属性动画定义在xml中,这种情况下就必须通过代码来动态地创建属性动画
7.插值器和估值器
TimeInterpolator时间插值器,作用是根据时间流逝的百分比计算出当前属性值改变的百分比(LinearInterpolator,AccelerateDecelerateInterpolaror,DecelerateInterpolator)
TypeEvaluator估值器根据当前属性改变的百分比来计算改变后的属性值(IntEvaluator、FloatEvaluator、ArgbEavluator)
属性动画要求对象属性有set方法和get方法
属性动画监听器AnimatorListener和AnimationUpdateListener
public static interface AnimatiorListener{
void onAnimationStart(Animatior animation);
void onAnimationEnd(Animatior animation);
void onAnimationCancel(Animatior animation);
void onAnimationRepeat(Animatior animation);
}
系统提供AnimatorListenerAdapter类,他是AnimatorListener的而适配类,这样就可以有选择地实现上面4个方法了
public static interface AnimatorUpdateListener{
void onAnimationUpdate(ValueAnimator animator);
}
AnimatorUpdateListener比较特殊,他会监听整个动画过程,动画是由帧组成的额,没播放一帧,onAnimatorUpdate就会被调用一次
8.对任意属性最动画
属性动画的原理
属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据外界传递的该属性的初始值和最终值,以动画的效果多次调用set方法,每次传递给set方法的值都不一样,确切的说是随着时间的推移,所传递的值越来越接近最终值。
总结,我们对Object的属性abc做动画,如果想让动画生效,需要满足两个条件
(1)object必须要提供setAbc方法,如果动画的时候没有传递初始值,那么还要提供getAbc方法,因此系统要去去abc属性的初始值(如果这个条件不满足,程序crash)
(2)object的setAbc对属性abc所做的改变必须能够通过某种方法反应出来,比如带来UI的改变之类的(如果这条不满足,动画无效果但不会crash
)
解决无setAbc和getAbc的控件使用属性动画的方法
(1)给你的对象加上get和set方法,如果你有权限的话
(2)用一个类包装原始对象,间接为其提供get和set方法
eg
private static class ViewWrapper{
private View mTarget;
public ViewWrapper(View target){
mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
(3)采用ValueAnimaor,监听动画过程吗,自己实现实行改变
private void performAnimate(final View target,final int start,final int end){
ValueAnimator valueAnimator = ValueAnimator.ofInt(1,100);
valueAnimator,addUpdateListener(new AnimatorUpdateListener(){
private IntEvaluator mEvaluator = new IntEvaluator();
@override
public void onAnimationUpdate(ValueAnimator animator){
int currentValue = (Integer)animator.getAnimatedValue();
float fraction = animator.getAnimateFraction();
target.getLayoutParams.width = mEvaluator.evaluator(fraction.start,end);
target.requestLayout();
}
});
valueAnimator.setDuration(5000),start();
}
9.使用动画的注意事项
(1)OOM 这个问题主要出现在帧动画中,当图片数量较多且图片较大时就极易出现OOM,尽量避免使用帧动画
(2)内存泄露 在属性动画中有一类无限循环的动画,这类动画需要在Activity退出时及时停止,否则将导致Activity无法释放从未造成内存泄露,通过验证后发现View动画不会出现此问题
(3)兼容性问题
(4)View动画问题,View是对View的影响做动画没并不是真正地改变View的状态,因此有时候会出现动画完成后View无法隐藏现象。即setVisible(View.GONE)失效了,这个时候只要调用view.clearAnimation()清除View的动画即可解决
(5)不要使用px
(6)动画元素交互 将View移动后,在Android3.0以前的系统上,不管是View动画还是属性动画,新位置均无法触发单击事件同时,老位置仍然可以触发单击事件。从3.0开始描述性动画的单击事件触发位置为移动后的位置,但view动画仍然在原位置