动画分类:
我这里将动画分为4类,补间动画(Tween),帧动画(Frame),属性动画(Property),画笔动态的画元素
1,补间动画
定义 :
补间动画是通过在两个关键帧之间补充渐变的动画效果来实现的。补间动画的优点是可以节省空间。
分类:
目前Android应用框架支持的补间动画效果有以下5种。具体实现在android.view.animation类库中。
1,AlphaAnimation:透明度(alpha)渐变效果,对应<alpha/>标签。
2,TranslateAnimation:位移渐变,需要指定移动点的开始和结 束坐标,对应<translate/>标签。
3,ScaleAnimation:缩放渐变,可以指定缩放的参考点,对应<scale/>标签。
4,RotateAnimation:旋转渐变,可以指定旋转的参考点,对应<rotate/>标签。
5,AnimationSet:组合渐变,支持组合多种渐变效果,对应<set/>标签。
补间动画的2种实现方式 :
1,在代码中动态定义动画,以位移动画为例:
TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0);
translateAnimation.setDuration(2000);
imageView.startAnimation(translateAnimation);
2,在xml文件中定义动画效果,以 透明度动画为例:alpha_demo.xml
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="2000"/>
<!--
fromAlpha :起始透明度
toAlpha:结束透明度
1.0表示完全不透明
0.0表示完全透明
-->
代码调用:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_demo);
imageView.startAnimation(animation);
android:interpolator 动画的渲染器
1、accelerate_interpolator(动画加速器) 使动画在开始的时候 最慢,然后逐渐加速
2、decelerate_interpolator(动画减速器)使动画在开始的时候 最快,然后逐渐减速
3、accelerate_decelerate_interpolator(动画加速减速器)
中间位置分层: 使动画在开始的时候 最慢,然后逐渐加速
使动画在开始的时候 最快,然后逐渐减速 结束的位置最慢
此属性也可以在代码中设置:
animation.setInterpolator(newAccelerateDecelerateInterpolator());
在ListView中设置每个条目出现的动画以及删除时的动画,可以在getview中对item View进行单独设置动画,当然如果我们需要的每个条目拥有相同的动画,那以下的2种方式无疑是最好的:
1,在layout布局文件中设置Listview的属性
android:layoutAnimation="@anim/listview_item_anim“
layoutAnimation内容如下:
2,在代码中对Listview设置layoutAnimation
2,帧动画
帧动画是一种常见的动画形式(FrameBy Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。因为逐帧动画的帧序列内容不一样,不但给制作增加了负担而且最终输出的文件量也很大,但它的优势也很明显:逐帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容,而它类似与电影的播放模式,很适合于表演细腻的动画。
实现方式: frameAnimation.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/percent_bg"android:duration="30"/>
<item android:drawable="@drawable/percent5"android:duration="30"/>
<item android:drawable="@drawable/percent10"</animation-list>
mPointer.setBackgroundResource(R.anim.frameAnimation);
AnimationDrawable animation = (AnimationDrawable)mPointer.getBackground();
animation.start();
3,属性动画
属性动画,这个是在Android 3.0中才引进的,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。
而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。
属性动画分类:
ValueAnimator
ValueAnimator包含PropertyAnimation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。
应用PropertyAnimation有两个步聚:
1,计算属性值
2,根据属性值执行相应的动作,如改变对象的某一属性。
ValuAnimiator只完成了第一步工作,如果要完成第二步,需要实现ValueAnimator.onUpdateListener接口,如:
ValueAnimator animation =ValueAnimator.ofFloat(0f, 1f);animation.setDuration(1000);
animation.addUpdateListener(newAnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("update",((Float)animation.getAnimatedValue()).toString());
}
});
animation.start();
按默认的10ms刷新一次,通过设置TimeInterpolation来改变刷新频率
360度旋转的代码
ObjectAnimator//
.ofFloat(view, "rotationX", 0.0F, 360.0F)//
.setDuration(500)//
.start();
属性动画的实现方式也有2种:
1,在XML中声明动画
属性动画系统会让你用XML来声明属性动画,而不是用编程的方式来做它。通过XML中定义你的动画,能够更加容易的在多个Activity中重用动画,并且更加容易的编辑动画的播放顺序。
从Android3.1开始,要把使用新的属性动画的API的动画文件与那些使用传统的视图动画框架区分开,你应该把属性动画的XML文件保存在res/animator/目录中(而不是res/anim/)。animator目录名是可选的,但是如果想要使用Eclipse ADT插件(ADT11.0.0+)中的布局编辑器,就必须使用animator目录,因为ADT只搜索res/animator目录中属性动画资源。
以下示例顺序的播放两组对象动画,第一组动画中嵌套了一个同时播放两个对象的动画:
<set android:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="intType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="intType"/>
</set>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1f"/>
</set>
为了运行这个动画,在代码中,必须把这个XML资源填充到一个AnimatorSet对象中,并且在开始播放这个动画集之前,要把这个动画集合设置给目标对象。调用setTarget()方法就可以方便的把AnimatorSet对象中的所有子对象设置给一个单一的目标对象。以下代码显示了做这件事的方法:
AnimatorSet set = (AnimatorSet)AnimatorInflater.loadAnimator(myContext,R.anim.property_animator);
set.setTarget(myObject);
set.start();
2,在代码中声明动画
下面介绍如果需要更改View的多个属性的动画,利用属性动画该如何实现,大家看下下面的例子:
ObjectAnimator anim = ObjectAnimator//
.ofFloat(view, “ccx", 1.0F, 0.0F)//
.setDuration(500);//
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
(1)本例子未指明View改变的具体属性,在属性一栏只是写了一个“ccx”的非View属性的字符串
(2)在onAnimationUpdate方法中我们更改了View的透明度,在水平和垂直方向View的缩放比例
前面介绍了用一个属性动画如果实现多个属性的更改,但是这些属性更改都是同时执行的,可能在一些情况下不会满足我们的需求。如果我们希望先执行某个属性的变化然后再执行另个属性的变化该如何实现呢?
方式1,对属性动画添加AnimatorListener监听,监听方法有如下几个
onAnimationStart,onAnimationRepeat,onAnimationEnd,onAnimationCancel,这几个方法的意思很明显,实现连续的属性变化的动画只需要在一个属性动画结束后再执行另外一个属性动画,即在onAnimationEnd中重新构建一个自己需要的属性动画。当然这种方法比较麻烦。我们下面介绍第二种实现方式。
方式2,使用用AnimatorSet类来编排多个动画
ObjectAnimatoranimX =ObjectAnimator.ofFloat(myView,"x", 50f);
ObjectAnimatoranimY =ObjectAnimator.ofFloat(myView,"y", 100f);
AnimatorSetanimSetXY = newAnimatorSet();
animSetXY.playTogether(animX,animY);
// animSetXY.play(animX).before(animY);
// animSetXY.play(animX).after(animY);
// animSetXY.play(animX).with(animY);
animSetXY.start();
上述的方法不限于2种动画我们可以继续在后面添加动画playTogether方法也可以加多个动画。
方式3 使用PropertyValuesHolder对象
PropertyValuesHolderpvhX =PropertyValuesHolder.ofFloat("x",50f);
PropertyValuesHolderpvhY =PropertyValuesHolder.ofFloat("y",100f);
ObjectAnimator.ofPropertyValuesHolder(mView,pvhX,pvhY).start();
方式4使用View的animate方法
mView.animate().x(50).y(100).alpha(0).start();
由于属性动画是android3.0之后才出现,所以在低版本手机上无法使用这些高版本的API,
这里可以使用nineoldandroids的jar包,它们会通过反射的方式实现属性动画的效果。但是像方式4这种就没法实现了因为它是应用的View的方法,nineoldandroids并未对此进行支持。
4,用动态画笔画元素
Android中的有一些表面看到的动画效果其实是在Canvas画布上画出来的效果,你可以在上面画你想画的东西。当然,你还可以设置画布的属性,如画布的颜色/尺寸等。
举个例子Booster项目中优化完成的圆圈就是通过画笔在Canvas上面画出来的。
int centre =mWidth/2;//获取圆心的x坐标
int radius = (int)(centre -mProgressWidth/2); //圆环的半径
mPaint.setAntiAlias(true); //消除锯齿
mPaint.setStyle(Style.FILL);
mPaint.setColor(mOutRoundColor);
mPaint.setStrokeCap(Cap.ROUND);
mPaint.setStrokeWidth(mProgressWidth);
mPaint.setColor(getResources().getColor(R.color.nq_53a544));
mPaint.setStyle(Style.STROKE);
canvas.drawCircle(centre, centre,radius,mPaint);
mPain是画笔,可以设置画笔颜色宽度等属性。 Canvas类除了drawCircle这个方法之外,还有很多画其他形状的方法,大家可以去尝试下,就不一一阐述了
在使用android基本动画中遇到的问题
1,使用帧动画时出现out of memory的异常崩溃
导致此问题出现主要是由于帧动画的每一帧的图片过大,或者播放的图片张数过多,所以使用帧动画时要实时注意这些方面。尤其是内存小的手机,很容易出现out of memory的情况。
2,OnCreate()中播放Animation动画,在低版本系统手机下无动画效果
默认情况下,不能在OnCreate()中执行animation.start();是无效的,因为在OnCreate()中View还未完全初始化完成。可以用HandlerpostDelay来延时执行动画。