1.View
动画XML
文件有固定语法,如下:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/out"
android:shareInterpolator="true">
</set>
set
动画集合里面可以包含若干动画,也可以嵌套其他动画集合。interpolator
表示动画集合的插值器,影响动画的速度。shareInterpolator
表示set
动画集合中的动画和其他集合是否共享一个插值器。如果父set
集合不指定插值器,子动画或子集合就得自己指定或使用默认的。
2.平移动画用translate
标签,如下:
<translate android:fromXDelta="100"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="100"/>
其中,fromXDelta
表示x的起始值,toXDelta
表示x的结束值,fromYDelta
和toYDelta
表示y方向的,按照android
坐标系,右、下为正
3.缩放动画用scale
标签,如下:
<scale android:fromXScale="2%"
android:toXScale="30%"
android:fromYScale="0"
android:toYScale="50%"
android:pivotX="10"
android:pivotY="30"
android:duration="3000"/>
其中,fromXScale
表示水平方向缩放的初始值,toXScale
为结束值;fromYScale
和toYScale
表示竖直方向的;pivotX
表示缩放轴点的x坐标,pivotY
表示缩放轴点的y坐标,轴点的坐标影响缩放效果,比如pivotX
为View
的左边界,那么就会向右缩放,而默认的pivotX
在View
的左上角。取值都有三种,具体数值(缩放起点为View左上角坐标加具体数值像素),百分比(在当前View左上角坐标加上View宽度的具体百分比),百分比+p(在View左上角坐标加上父控件宽度的具体百分比)。
4.旋转动画用rotate
标签,如下:
<rotate android:fromDegrees="100"
android:toDegrees="80"
android:pivotY="50"
android:pivotX="50"/>
其中,fromDegrees
表示旋转开始的角度,toDegrees
表示旋转结束的角度,pivotY
表示旋转轴点的y坐标,pivotX
表示旋转轴点的x坐标,轴点的坐标影响缩放效果,比如View
绕着自己的某个角旋转和绕中心旋转效果肯定不一样,默认是绕着view的左上角旋转。
5.透明度动画用alpha
标签,如下:
<alpha android:fromAlpha="0.1"
android:toAlpha="0.9"/>
其中,fromAlpha
表示透明度的起始值,toAlpha
表示透明度的结束值,范围0.0-1.0。
6.上述四种动画都有以下两个属性,android:duration
表示动画持续的时间,单位毫秒;android:fillAfter
表示动画结束后View
是否停留在结束的位置,注意fillAfter
必须加在set
标签里面才起作用。
7.动画的应用分xml
文件应用和代码应用。如下:
XML动画应用:
Animation animation = AnimationUtils.loadAnimation(context,R.anim.animation);
animation.setDuration(300);
button.startAnimation(animation);
代码应用:
Animation animation = new AlphaAnimation(0,1);
animation.setDuration(300);
button.startAnimation(animation);
8.通过animation.setAnimationListener(animationListener)
方法可以给动画设置监听,animationListener
内部包含如下回调方法:
void onAnimationStart(Animation animation);//开始动画
void onAnimationEnd(Animation animation);//结束动画
void onAnimationRepeat(Animation animation);//重复动画
9.帧动画用animation-list
标签,系统提供AnimationDrawable
来使用帧动画,如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/shape" android:duration="100"/>
<item android:drawable="@drawable/shape_round1" android:duration="100"/>
<item android:drawable="@drawable/shape_round2" android:duration="100"/>
<item android:drawable="@drawable/shape_round3" android:duration="100"/>
</animation-list>
button.setBackgroundResource(R.drawable.animation_list);
AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground();
animationDrawable.start();
需要注意的是,不要使用过多过大的图片资源,否则会造成OOM。
10.layoutAnimation
用于为ViewGroup
指定动画,这样它的子元素出场时就有了这种动画,如下:
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="normal"
android:animation="@anim/out">
</layoutAnimation>
其中,delay
表示子元素开始动画的延时系数,比如delay
为0.5,这个动画的周期为100ms,那么第一个子元素的入场延时为50ms,第二个延时100ms,以此类推。
animationOrder
表示子元素动画的顺序,分为:normal
(顺序),reverse
(逆序),random
(随机)。
animation
表示为子元素指定的动画。
layoutAnimation
的使用方法有两种:一种是在xml
文件的ViewGroup
里面指定android:layoutAnimation
属性;一种是在代码里使用,如下:
Animation layoutAnimation = AnimationUtils.loadAnimation(this,R.anim.out);
LayoutAnimationController controller = new LayoutAnimationController(layoutAnimation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
11.Activity
的切换动画,通过activity.overridePendingTransition(inAnimId, outAnimId)
方法来实现,inAnimId
表示Activity
被打开时所需的动画资源id,outAnimId
表示Activity
被暂停时所需的动画资源id。需要注意的是,这个方法必须在startActivity()
或activity.finish()
后调用,不然无法生效。
Fragment
切换可以通过transaction.setCustomAnimations()
方法设置动画效果,注意这个动画必须是View
动画。
12.属性动画可以对任何对象的属性进行动画,注意是任何对象,动画默认时间间隔300ms,默认帧率10ms/帧。开源动画库nineoldandroids
可以兼容API11
以前的版本。建议在代码中使用属性动画,xml
中定义的属性动画可能无法明确初始值。XML
使用方式如下:
AnimatorSet set = AnimatorInflater.loadAnimator(context,animationResId);
set.setTarget(button);
set.start();
13.ObjectAnimator
是ValueAnimator
的子类,使用如下:
ObjectAnimator objectAnimator = new ObjectAnimator();
objectAnimator.setTarget(button);//目标对象
objectAnimator.setPropertyName("translationX");//改变的属性
objectAnimator.setFloatValues(-100f);//改变属性的变化值集合
objectAnimator.setDuration(1000);//时间间隔,单位ms
objectAnimator.setRepeatCount(-1);//循环次数,默认为0,-1表示无限循环
objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);//循环模式,RESTART表示每次完了都从头开始,REVERSE表示每次完了后会倒过来播放
objectAnimator.start();
14.ValueAnimator
的使用如下:
ValueAnimator valueAnimator = ObjectAnimator.ofInt(button,"backgroundColor",0xffffffff,0x00000000);
valueAnimator.setDuration(3000);
valueAnimator.setEvaluator(new ArgbEvaluator());
objectAnimator.setRepeatCount(100);//循环次数,默认为0,-1表示无限循环
objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);//循环模式,RESTART表示每次完了都从头开始,REVERSE表示每次完了后会倒过来播放
valueAnimator.start();
15.AnimatorSet使用如下:
AnimatorSet animatorSet = new AnimatorSet();
//子动画同时播放
animatorSet.playTogether(
ObjectAnimator.ofFloat(button,"translationX",-100),
ObjectAnimator.ofFloat(button,"rotationX",0,300)
);
//子动画按先后顺序播放
animatorSet.playSequentially(
ObjectAnimator.ofFloat(button,"translationX",-100),
ObjectAnimator.ofFloat(button,"rotationX",0,300)
);
animatorSet.setDuration(30000);
animatorSet.start();
16.TimeInterpolator
(插值器)常用的有LinearInterpolator
(线性插值器,用于匀速动画),AccelerateDecelerateInterpolator
(加速减速插值器,动画两头慢,中间快),DecelerateInterpolator
(减速插值器,动画越来越慢)。TypeEvaluator
(估值器)常用的有IntEvaluator
(整型估值器),FloatEvaluator
(浮点型估值器),ArgbEvaluator
(颜色估值器)。
17.属性动画要求动画作用的对象必须提供要改变的属性有效的get、set
方法,否则可能没效果(该属性set
方法没有实际改变UI效果)或者直接crash
(该属性没有get、set
方法)。
18.动画应用注意事项:
1.注意OOM问题,特别是帧动画。
2.属性动画如果是无限循环的,那么在activity销毁的时候一定要调用动画的cancel方法。
3.View动画是对View的影像动画,并不是真正改变View的状态,有时setVisibility方法会失效,在之前调用clearAnimation方法可以解决。
4.View动画的点击等监听事件,在动画完成后,监听事件还是原来的位置,因为动画的只是影像。
示例代码:
public class AnimationActivity extends AppCompatActivity {
@BindView(R.id.button1)
Button button1;
@BindView(R.id.button2)
Button button2;
@BindView(R.id.button3)
Button button3;
@BindView(R.id.button4)
Button button4;
@BindView(R.id.button5)
Button button5;
@BindView(R.id.button6)
Button button6;
@BindView(R.id.button7)
Button button7;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
ButterKnife.bind(this);
}
@OnClick({R.id.button1, R.id.button2, R.id.button3, R.id.button4, R.id.button5, R.id.button6, R.id.button7})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button1:
showAlpha();
break;
case R.id.button2:
showRotate();
break;
case R.id.button3:
showScale();
break;
case R.id.button4:
showTranslate();
break;
case R.id.button5:
showObjectAnimator();
break;
case R.id.button6:
showValueAnimator();
break;
case R.id.button7:
showAnimatorSet();
break;
}
}
private void showAlpha(){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.alpha);
button1.startAnimation(animation);
}
private void showRotate(){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
button2.startAnimation(animation);
}
private void showScale(){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.scale);
button3.startAnimation(animation);
}
private void showTranslate(){
Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
button4.startAnimation(animation);
}
private void showObjectAnimator(){
ObjectAnimator animator= ObjectAnimator.ofFloat(button5,"translationY",10,20,30,20,10,0,-10,-20,-30,-20,-10,0);
animator.setDuration(3000);
animator.start();
}
private void showValueAnimator(){
ValueAnimator animator = ObjectAnimator.ofInt(button6,"backgroundColor",0xffffffff,0xff000000);
animator.setDuration(3000);
animator.setEvaluator(new ArgbEvaluator());
animator.start();
}
private void showAnimatorSet(){
ObjectAnimator animator1= ObjectAnimator.ofFloat(button7,"translationX",0,20,40,60,80,100,120);
animator1.setDuration(3000);
ObjectAnimator animator2= ObjectAnimator.ofFloat(button7,"translationY",0,-10,-20,-30,-40,-50);
animator2.setDuration(3000);
ObjectAnimator animator3= ObjectAnimator.ofInt(button7,"backgroundColor",0xffff0000,0xff0000ff);
animator3.setEvaluator(new ArgbEvaluator());
animator3.setDuration(3000);
AnimatorSet set = new AnimatorSet();
set.playSequentially(animator1,animator2,animator3);
set.start();
}
}
xml文件:
平移动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate android:fromXDelta="0"
android:toXDelta="280"
android:fromYDelta="0"
android:toYDelta="-60"
android:duration="3000"/>
</set>
缩放动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale android:fromXScale="0"
android:toXScale="80%"
android:fromYScale="0"
android:toYScale="50%"
android:pivotX="10"
android:pivotY="30"
android:duration="3000"/>
</set>
旋转动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<rotate android:fromDegrees="0"
android:toDegrees="-180"
android:pivotY="50%"
android:pivotX="50%"
android:duration="3000"/>
</set>
透明度动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<alpha android:fromAlpha="0.1"
android:toAlpha="0.9"
android:duration="3000" />
</set>
网友评论