动画
sky-mxc 总结 转载注明:https://sky-mxc.github.io
- 帧动画
- 补间动画
- 属性动画
- Interpolator
帧动画 FrameAnimation
其实就是一个Drawable ,将一系列的图片联合起来顺序的播放。形成动画效果。
帧动画本质就是一些图片的集合,要播放这个动画就必须将一系列的图片全部加载进内存中,所以帧动画的图片不易过大。
创建drawable文件
- oneshot :是否只播放一次,
- drawable :一帧的图片
- duration :一帧播放的时间 毫秒单位
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="@mipmap/a_01" android:duration="200"/>
<item android:drawable="@mipmap/a_02" android:duration="200"/>
<item android:drawable="@mipmap/a_03" android:duration="200"/>
<item android:drawable="@mipmap/a_04" android:duration="200"/>
<item android:drawable="@mipmap/a_5" android:duration="200"/>
<item android:drawable="@mipmap/a_6" android:duration="200"/>
</animation-list>
使用刚才的drawable文件做背景
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:background="@drawable/drawable_frame"
android:clickable="true"
android:onClick="onClick"/>
播放动画
//FrameAnimation 帧动画
((AnimationDrawable)image.getBackground()).start();
补间动画 tweenAnimation
主要是对view的内容完成一系列的图形变换(缩放,透明,旋转,平移)来实现动画效果。
具体来说就是 预先定义一些指令 ,这些指令指定了图形变换的类型,触发时间,持续时间。指令可以预先定义在xml文件中也可以源代码的方式定义。程序沿着时间线执行这些指令就可以实现动画效果。
Android中提供了 Animation,Interpolator,Transformation 等类具体实现Tween动画,
Animation类及其子类是动画的核心模块,它实现了 各种动画效果如 平移 旋转 缩放 改变透明度等等。
Tween动画的每一帧都根据Interpolator对view的内容做一次图像变换,因此Animation的核心工作是做变换(transformation);
Animation是基类 ,它记录了动画的通用属性和方法。主要的属性包括动画持续时间、重复次数、Interpolator等。
常用属性
- duration :动画时间 毫秒
- infinite :无限次
- fillAfter 是否停顿在最后一针
- repeatMode 重复模式 值:restart 重新开始 reserve 反复
- repeatCount :重复次数
- startOffset :开始延迟时间
常用Animation子类:
- AlphaAnimation 改变Alpha值
- TranslationAnimation 平移动画
- RotateAnimation 旋转动画
- ScaleAnimation 缩放动画
- AnimationSet 动画集合
实例
补间动画 既可以使用 xml文件预先定义 也可以使用代码动态创建;
使用xml文件定义必须在 res/anim/目录下创建 文件;
可以使用 AnimationUtils的静态方法 loadAnimation()将动画文件加载
AlphaAnimation 透明度改变动画
定义 AlphaAnimation 文件
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1"
android:toAlpha="0.1"
android:duration="2000"
android:repeatCount="5"
android:repeatMode="reverse">
</alpha>
加载 动画文件并播放
//AlphaAnimation xml定义
AlphaAnimation alphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_alpha);
view.startAnimation(alphaAnimation);
代码创建
//AlphaAnimation 代码创建
AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.1f,0.8f);
alphaAnimation1.setDuration(2000);
alphaAnimation1.setStartOffset(100);
alphaAnimation1.setFillAfter(true);
alphaAnimation1.setRepeatCount(2);
alphaAnimation1.setRepeatMode(Animation.REVERSE);
view.startAnimation(alphaAnimation1);
TranslationAnimation 平移动画
- fromXDelta X轴开始坐标
- toXDelta X轴结束坐标
- fromYDelta Y 轴开始坐标
- toYDelta Y轴结束坐标
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:toXDelta="300"
android:repeatMode="reverse"
android:repeatCount="3"
android:fillBefore="true"
android:fromYDelta="200"
android:toYDelta="100">
</translate>
加载动画并播放
TranslateAnimation translateAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_translation);
view.startAnimation(translateAnimation);
代码创建动画
TranslateAnimation translateAnimation1 = new TranslateAnimation(-10,100,0,0);
translateAnimation1.setInterpolator(new BounceInterpolator());
translateAnimation1.setDuration(2000);
view.startAnimation(translateAnimation1);
RotateAnimation 旋转动画
- fromDegrees:起始角度
- toDegrees:到达角度
- pivotX:X轴中心点
- pivotY:Y轴中心点
中心点取值模式:
- 固定像素 50
- 相对于自身 50%
- 相对于父容器 50%p
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="90"
android:fromDegrees="0"
android:duration="2000"
android:fillAfter="true">
</rotate>
加载动画并播放
RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_rotate);
view.startAnimation(rotate);
代码创建动画
//在右上角中心,0-180度
RotateAnimation rotate = new RotateAnimation(0, 180);
//(100,100)像素位中心
RotateAnimation rotate = new RotateAnimation(0, 180, 100, 100);
//相对于自身一半为中心
RotateAnimation rotate = new RotateAnimation(0, 180,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
沿中心旋转 45°
RotateAnimation rotateAnimation = new RotateAnimation(0,45,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new DecelerateInterpolator());
rotateAnimation.setDuration(2000);
rotateAnimation.setFillAfter(true);
view.startAnimation(rotateAnimation);
ScaleAnimation 缩放动画
- fromXScale:X轴起始缩放值
- fromYScale:Y轴起始缩放值
- toXScale:X轴到达缩放值
- toYScale:Y轴到达缩放值
- 缩放值可以是缩放倍数,也可以是缩放到具体尺寸
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="2"
android:fromYScale="0"
android:toYScale="3"
android:duration="2000"
android:pivotY="50%"
android:pivotX="50%">
</scale>
加载动画并播放
ScaleAnimation scale = (ScaleAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_scale);
view.startAnimation(scale);
代码创建动画
ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2);
ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2, 100, 100);
ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2,Animation.RELATIVE_TO_PARENT, 0.5f,Animation.RELATIVE_TO_PARENT, 0.5f);
AnimationSet 动画集合
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000">
<rotate android:pivotX="0"
android:pivotY="0"
android:fromDegrees="-180"
android:toDegrees="0"/>
<scale android:pivotX="50%"
android:pivotY="50%"
android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"/>
</set>
加载动画并播放
Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_set);
view.startAnimation(animation);
代码创建动画
//子动画是否共用差值器
AnimationSet set = new AnimationSet(true);
set.addAnimation(new RotateAnimation(-180,0));
set.addAnimation(new ScaleAnimation(0,1,0,1,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f));
set.setDuration(2000);
set.setFillAfter(true);
view.startAnimation(set);
Interpolator
Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。
常用的差值器
- LinearIntepolator 匀速效果
- DecelerateInterpolator 减速效果
- Accelerateinterpolator 加速效果
- CycleInterpolator 循环效果
- BouncedInterpolator 弹跳效果
Property Animation 属性动画
属性动画的用处有很多很多,我就列几个常用的方式把;具体参考官网文档:https://developer.android.com/guide/topics/graphics/prop-animation.html
补间动画并不能改变view真实的位置,只是形式上的位置改变。而属性动画会将view的真实位置改变。
属性动画定义必须在 res/animator目录下
ValueAnimation
valueType 常用三种取值:
- intType整数值、
- floatType浮点值、
- colorType颜色值、
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="2"
android:valueTo="200"
android:duration="2000"
android:valueType="intType"
android:interpolator="@android:interpolator/linear">
</animator>
加载动画 并添加 动画监听
属性动画 就是在 监听中去改变控件的属性的值 ,让控件 位置和形态的属性都发生真正的变化
ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_value);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//intType
int value= (int) animation.getAnimatedValue();
image.setTranslationY(value);
// image.setTranslationX(value);
//floatType
// float alpha = (float) animation.getAnimatedValue();
// image.setAlpha(alpha);
}
});
代码创建
// ValueAnimator valueAnimator = ValueAnimator.ofFloat(1f,0.5f,0f);
PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha",1f,0.5f);
PropertyValuesHolder widthHolder = PropertyValuesHolder.ofInt("width",1,200);
PropertyValuesHolder rotateHolder = PropertyValuesHolder.ofFloat("rotate",0,180);
ValueAnimator valueAnimator = ValueAnimator.ofPropertyValuesHolder(alphaHolder,widthHolder,rotateHolder);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// float value= (float) animation.getAnimatedValue();
// image.setAlpha(value);
float alpha= (float) animation.getAnimatedValue("alpha");
int width = (int) animation.getAnimatedValue("width");
float rotate = (float) animation.getAnimatedValue("rotate");
Log.e("MainActivity","alpha:"+alpha);
Log.e("MainActivity","width:"+width);
image.setAlpha(alpha);
image.setMaxWidth(width);
image.setMinimumWidth(width);
image.setRotation(rotate);
}
});
valueAnimator.setDuration(2000);
valueAnimator.start();
ObjectAnimator
大部分属性都和ValueAnimator相同,只多了对要控制改变的控件的属性的声明
propertyName:要控制的控件的属性名;
动画会直接修改制定属性名的属性需要注意:设置了getter/setter方法的属性才能生效
定义动画文件
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="45"
android:duration="2000"
android:valueType="floatType">
<!--
rotation
rotationY
rotationX
-->
</objectAnimator>
加载动画并设置播放动画的对象
ObjectAnimator object = (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_object);
object.setTarget(image);
object.start();
代码创建动画
凡是 有get/set方法的属性都可以设置值
// ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(image,"alpha",1f,0.2f);
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(view,"backgroundColor", Color.RED,Color.YELLOW,Color.BLUE,Color.GREEN);
objectAnimator.setDuration(2000);
objectAnimator.setInterpolator(new BounceInterpolator());
objectAnimator.start();
完整代码github地址:https://github.com/sky-mxc/AndroidDemo/tree/master/animation