帧动画
Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package,Android SDK提供了另外一个类AnimationDrawable来定义使用Frame Animation。
利用xml文件实现:res/drawable-hdpi/frame.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/p1" android:duration="1000"/>
<item android:drawable="@drawable/p2" android:duration="1000"/>
<item android:drawable="@drawable/p3" android:duration="1000"/>
</animation-list>
- 使用帧动画
AnimationDrawable anim = (AnimationDrawable)getResources().
getDrawable(R.drawable.frame);
textWidget = (TextView)findViewById(R.id.text_widget);
textWidget.setText("背景渐变动画效果");
textWidget.setBackgroundDrawable(anim);
anim.start();
TweeAnimation 补间动画
只可以改变两个关键帧之间的透明度,旋转,缩放,位移四个变化
AlphaAnimation
RotateAnimation
ScaleAnimation
TranslateAnimation
1、 设置动画的资源文件
- 补间动画的资源文件
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="10%"
android:pivotY="10%"
android:repeatCount="3"
android:repeatMode="restart"
android:toXScale="0.5"
android:toYScale="2.0"
>
<!-- android:repeatMode="reverse"
android:repeatCount="5"-->
<!--缩放动画 repeatCount重复字数,指的完成首次后再重复几次 repeatMode="reverse" reverse指的是按照动画的逆序再回来-->
</scale>
animation=AnimationUtils.loadAnimation(this, R.anim.anim_1);//加载动画资源
btn.startAnimation(animation);//启动动画
2、 直接在代码中设置动画
RotateAnimation animation = new RotateAnimation(0, 2700);//创建动画
animation.setDuration(10000);//设置时长
animation.setRepeatCount(5);//设置重复次数
animation.setInterpolator(new AnticipateInterpolator());//设置插值器
animation.setAnimationListener(this);//设置监听
mButton1.startAnimation(animation);//启动动画
TimeInterpolator和TypeEvaluator
TimeInterpolator中文翻译为时间插值器,它的作用是根据时间流逝的百分比来计算出当前属性值改变的百分比
系统预置的有LinearInterpolator(线性插值器:匀速动画)、AccelerateDecelerateInterpolator(加速减速插值器:动画两头慢中间快)和DecelerateInterpolator(减速插值器:动画越来越慢)等
TypeEvaluator的中文翻译为类型估值算法,它的作用是根据当前属性改变的百分比来计算改变后的属性值
系统预置的有IntEvaluator(针对整型属性)、FloatEvaluator(针对浮点型属性)和ArgbEvaluator(针对Color属性)
为补间动画添加插值器Interpolator
- 几种插值器
- 越来越快 AccelerateInterpolator()
- 越来越慢 DecelerateInterpolator()
- 先快后慢 AccelerateDecelerateInterpolator()
- 先后退一小步然后向前加速 AnticipateInterpolator()
- 快速到达终点超出一小步然后回到终点 OvershootInterpolator()
- 到达终点超出一小步然后回到终点 AnticipateOvershootInterpolator()
- 弹球效果,弹几下回到终点 BounceInterpolator()
- 均匀速度 LinearInterpolator()
属性动画
ValueAnimation
属性动画的基类,ObjectAnimation是集成自该类。ValueAnimator.ofFloat()方法中传递的可变参数,使用监听方法onAnimationUpdate拿到动画变化的属性值,再去对需要设置动画的属性赋值。
这个方法中的参数是一个可变参数
ValueAnimator valueAnimator = ValueAnimator.ofFloat(100f, 300f);//创建一个属性动画,里面的两个参数,代表是动画的属性值
valueAnimator.setDuration(2000);
valueAnimator.setTarget(iv);//设置动画的目标
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//设置更新的事件
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float f = (float) valueAnimator.getAnimatedValue();//获取到当前动画执行到的值
iv.setTranslationX(f);//将值作为位移的参数设置给控件,设置的相对参数
iv.setX(f);//设置的是绝对参数
}
});
valueAnimator.start();
ObjectAnimation
是ValueAnimation的子类,可以方便的对某个空间设置属性动画,该方法实际上是调用了改对象的set方法,只要是该控件具有该属性的set方法,就可以对其设置动画
/**
* 对textView的字体大小设置动画
*/
ObjectAnimator textSize = ObjectAnimator.ofFloat(tv, "textSize", 10, 30);
textSize.setDuration(3000);
AnimatorSet
属性动画的集合
ObjectAnimator alpha = ObjectAnimator.ofFloat(tv, "alpha", 0.1f, 0.9f, 0.8f);
ObjectAnimator textSize = ObjectAnimator.ofFloat(tv, "textSize", 10, 30);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.2f, 3.8f, 10f, 1.4f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.2f, 3.8f, 10f, 1.4f);
ObjectAnimator translationX = ObjectAnimator.ofFloat(iv, "translationX", 0, 300f);
//位移动画集合
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(5000);
animatorSet.play(alpha).with(translationX).before(textSize).after(scaleX);//自定义顺序
//animatorSet.playTogether(alpha,textSize,scaleX,scaleY,translationX);//所有的动画一起播放
//animatorSet.playSequentially(alpha,textSize,scaleX,scaleY,translationX);//将参数中的所有动画按照顺序一个一个播放
animatorSet.start();
PropertyValuesHolder
可以添加多个属性动画。
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0.1f, 0.9f, 1.0f);
PropertyValuesHolder textSize = PropertyValuesHolder.ofFloat("textSize", 10, 30);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.2f, 1.0f, 0.5f);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.2f, 1.0f, 0.5f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(tv, alpha, textSize, scaleX, scaleY);
objectAnimator.setDuration(5000);
objectAnimator.start();
AnimatorInflate
通过xml文件定义属性动画
- 加载属性动画资源的方法
Animator set = AnimatorInflater.loadAnimator(this, R.animator.set);
set.setTarget(tv);
set.start();
- 动画属性资源的实例
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="100dp"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:valueType="floatType">
</objectAnimator>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="scaleX"
android:valueType="floatType"
android:valueTo="3"
>
</objectAnimator>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially"
>
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="100px"
android:duration="3000"
android:interpolator="@android:anim/bounce_interpolator"
android:valueTo="500px"/>
<objectAnimator
android:propertyName="scaleX"
android:valueType="floatType"
android:valueFrom="0.5"
android:duration="5000"
android:valueTo="3.0" />
</set>
自定义的属性动画
如果想要做动画的属性在控件中不存在,那么就需要自定义的属性动画
/**
* 用于自定义修改控件的属性。textView的宽度是需要通过父控件获得的,所以需要通过自定义的MyObject获得
*/
MyObject myObject = new MyObject(tv);
ObjectAnimator width = ObjectAnimator.ofInt(myObject, "width", 10, 100, 200, 300, 400, 1000);
width.setDuration(5000);
width.start();
- 在定义的MyObj方法中获得textView 的宽度,在属性动画中调用
public class MyObject {
private int width;
private View view;
public MyObject(View view) {
this.view = view;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
view.getLayoutParams().width = width;
view.requestLayout();//请求重绘
}
}
属性动画的另一种写法
Property property = Property.of(TextView.class, float.class, "textSize");//创建一个属性对象, 宿主类型 Tetxview, 参数值类型float, 参数名textSize
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv, property, 10, 20, 30, 40, 50);
objectAnimator.setDuration(5000);
objectAnimator.start();
动画的常见使用场景
在ViewGroup中控制子元素的出场效果
1、 在anim文件夹中给ViewGroup设置动画
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/animation_item"
android:animationOrder="normal"
android:delay="0.2">
<!--animation 给子控件设置动画资源-->
<!--animationOrder 是定义子控件的出场顺序-->
<!--delay 是定义两个子控件的动画延迟时间,0.2是延迟的倍数-->
</layoutAnimation>
2、 在anim文件夹中给子控件设置动画效果
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:interpolator="@android:interpolator/anticipate"
android:shareInterpolator="true"
>
<alpha
android:fromAlpha="0"
android:toAlpha="1"/>
<translate
android:fromXDelta="500"
android:toXDelta="0"/>
</set>
- 这种方式也可在代码中通过
LayoutAnimationController
设置
Activity,Fragment的切换效果
1、 设置activity的场景转换动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:interpolator="@android:interpolator/anticipate"
android:shareInterpolator="true">
<rotate
android:fromDegrees="90"
android:toDegrees="0"/>
<translate
android:fromXDelta="500"
android:toXDelta="0"
/>
</set>
2、 启动activity的时候设置activity的转场动画,调用方法 overridePendingTransition
,该方法必须在startActivity方法和finish方法之后调用才有效果
Intent intent = new Intent(this, SeconActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.activity_enter, R.anim.activity_out);
//分别设置进场和出场的动画效果