一:ValueAnimator类
1.ValueAnimator是属性动画中一个比较重要的类。我们知道属性动画和补间动画不同的是,补间动画并不是直接对View进行操作,而是在进行位移,旋转等等动画后绘制的结果。我们点击动画后的View发现并不能触发点击事件,而属性动画则是完全对View的操作。ValueAnimator用于处理初始值到结束值之间过渡,它的内部使用时间处理机制来让动画平滑的过渡。平时使用的场景并不多,我们可以这样使用:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300); //用于设置动画持续时间
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
这里我们设置了一个监听器,用于监听值的不断变化。最后记得要start()方法启动动画。实现的效果是将动画从0到1过渡期间的值给打印出来。里面比较常用的方法是ofFloat(),ofInt(),里面的值可以有很多。
二:ObjectAnimator类
ObjectAnimator类直接继承ValueAnimator类,平时用处更广。所以,以上对VauleAnimator类的所有操作,用ObjectAnimarot也都是可以用的。
例如对透明的的动画操作:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
这里我们调用了ofFloat()方法创建了一个animator对象实例,但是我们发现ifFloat()参数有变化,第一个参数是要求传入一个object对象,这里我传入了一个textview对象,让textview出现动画效果。第二个参数是动画类型,第三个参数是不定长值,我们可以传入多组数据,这里表示textview的透明的从1变为0,再从0变为1.
常用的动画类型:
1.透明度”alpha”
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
2.旋转”rotation”
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
将textview按照中心点实现360度旋转。
自定义中心点旋转(注意,参照点为组件的左上角)
倘若我不想让textview沿中心点旋转而是想让它按组件下边缘的中点旋转,可以这样实现:
重新设置旋转点pivotX和pivotY
textView.setPivotX(textView.getWidth()/2);
textView.setPivotY(textView.getHeight());
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
3.X轴平移操作”translationX”
这里我们想先让textview向左移出屏幕,再移回来(注意:ofFloat()里边的不定参数是相对位置坐标而不是位移量。)
float curTranslationX = textview.getTranslationX();
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);
animator.setDuration(5000);
animator.start();
这里我们先用textview调用了getTranslationX()方法来获取当前textview的位置,然后我们后面追加位置,最后再移回最开始textv所在的位置。
同理在Y轴上平移操作类似
4.Y轴缩放操作”scaleY”
在Y轴上放大三倍再还原可以这样写。
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
animator.setDuration(5000);
animator.start();
X轴同理。
到这里基本上常用的动画属性都总结完了,但是否只有这些动画属性呢?不是,我们知道我们之前所填入的第二个参数事实上并没有这个方法,那动画为何会实现呢?原因是因为在view里面有有关这些的set和get方法,所所以在我们使用的时候,系统自动去view的所有方法里面去寻找有关的set和get方法来实现。因此,所有继承view的控件都能够使用这些动画属性。
三.AnimotorSet类组合动画
我们知道以上总结的都是独立动画,往往单个独立动画并不能满足我们的需求,我们可以借助AnimatorSet来实现组合动画的功能。这个类提供了一个play()方法,我们往里传入一个Animator对象会返回一个AnimatorSet.Builder,其中Animator.Builder中包括以下四个方法:
1.after(Animator anim)将现有动画插入到传入的动画之后执行
2.after(long delay)将现有动画延迟指定毫秒之后执行
3.before(Animator anim)将现有动画插入到传入的动画之前执行
4.with(Animator anim)将现有动画和传入动画同时执行
例子:先将textview向右平移,然后旋转并且淡入淡出
rotateAnimator=ObjectAnimator.ofFloat(tv,"rotation",0f,360f);
moveinAnimator=ObjectAnimator.ofFloat(tv, "translationX",0f,300f);
fadeinoutAnimator=ObjectAnimator.ofFloat(tv, "alpha", 1f,0f,1f);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(rotateAnimator).after(moveinAnimator).with(fadeinoutAnimator);
animatorSet.setDuration(3000);
animatorSet.start();
play()方法先传入一个现有动画,然后再调用after()和with()方法插入动画,所以可以这样理解:旋转动画在平移动画之后执行,并且和淡入淡出一起执行。所以此时传入的动画的参照点都是先指定的现有动画,即paly()方法里传入的动画。
四:Animator监听器
Animator中提供了一个addListener方法,实现AnimatorListener就能对动画的监听
animatorSet.addListener(new AnimatorListener() {
public void onAnimationStart(Animator animation) {//动画开始时调用
}
public void onAnimationRepeat(Animator animation) {//动画重复执行时调用
}
public void onAnimationEnd(Animator animation) {//动画结束时调用
}
public void onAnimationCancel(Animator animation) {//动画取消时调用
}
});
五:另一种动画功能的编写
我们除了可以通过java代码编写动画,还能通过xml文件编写动画,虽说编写的慢一点,但优点在于我们可以在其他地方也调用动画,提高了代码的重用性。编写好xml文件我们可以轻松的在任何地方启用动画。
如何编写动画xml文件
首先在res文件夹下边新建一个animator文件夹,所有的xml动画都保存在这个文件夹当中,我们可用下面三种标签:(与我们之前所总结的三个类相对应)
对应代码中的ValueAnimator
对应代码中的ObjectAnimator
对应代码中的AnimatorSet
1.如果我们要编写一个从0-100平滑过渡的动画:
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:valueType="intType"/>
2.如果我们要实现一个从0-1透明度渐变的动画
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"/>
3.如果我们要编写一个组合动画
一样是先从屏幕外移动进入,再旋转的同时渐变
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially" >
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<set android:ordering="together" >
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
<set android:ordering="sequentially" >
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" >
</objectAnimator>
</set>
</set>
</set>
xml文件我们写好了,接下来在java代码中加载它们并启动它们
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view);
animator.start();
我们先用AnimatorInflater的loadAnimator方法将动画加载进来给animator,然后把动画通过setTarget设置给我们需要动画的组件对象,最后启动动画就实现了动画的编写和启动。