逐帧动画和补间动画的使用(一)
1.什么叫做动画?
动画有三种:逐帧动画,补间动画,属性动画。至于属性动画我们下节在讲
- 同一个图形通过视图在界面上进行透明度,缩放,旋转,平移变换(补间动画)
- 在界面上同一个位置不断的切换显示不同的图片,类似于动画片的工作原理( 逐帧动画)
2.动画的分类
- View Animation
- Drawable Animation
- ValueAnimator(我们下节重点来讲)
3.Android中提供了两种实现动画的方式
- •纯编码的方式
- •Xml配置的方式
4.直接上案例:
4.1补间动画:
Activity的布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startCodeScale"
android:text="Code Scale" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startXmlScale"
android:text="Xml Scale" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startCodeRotate"
android:text="Code Rotate" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startXmlRotate"
android:text="Xml Rotate" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startCodeAlpha"
android:text="Code Alpha" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startXmlAlpha"
android:text="Xml Alpha" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startCodeTranslate"
android:text="Code Translation" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startXmlTranslate"
android:text="Xml Translation" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startCodeAnimationSet"
android:text="Code AnimationSet"
android:textSize="15sp"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="startXmlAnimationSet"
android:text="Xml AnimationSet"
android:textSize="15sp"/>
</LinearLayout>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="testAnimationListener"
android:text="Test Animation Listener"/>
<ImageView
android:id="@+id/iv_animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/fly"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/tv_animation_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示动画描述信息"
android:textSize="18dp"/>
</LinearLayout>
动画文件:
主Activity:
/**
* Created by quguangle on 2016/12/1.
*/
/*
* 编码实现View Animation
* 1. Code方式
* 2. Xml方式
*/
public class VAActivity extends Activity {
private ImageView iv_animation;
private TextView tv_animation_msg;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation_va);
iv_animation = (ImageView) findViewById(R.id.iv_animation);
tv_animation_msg = (TextView) findViewById(R.id.tv_animation_msg);
}
/*
* 1.1 编码实现: 缩放动画
* ScaleAnimation
*/
/*
//1. 创建动画对象
//2. 设置
//3. 启动动画
*/
public void startCodeScale(View v) {
tv_animation_msg.setText("Code缩放动画: 宽度从0.5到1.5, 高度从0.0到1.0, 缩放的圆心为顶部中心点,延迟1s开始,持续2s,最终还原");
//1. 创建动画对象
ScaleAnimation animation = new ScaleAnimation(0.5f, 1.5f, 0, 1,
Animation.ABSOLUTE, iv_animation.getWidth()/2, Animation.ABSOLUTE, 0);
animation = new ScaleAnimation(0.5f, 1.5f, 0, 1,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0);
//2. 设置
//延迟1s开始
animation.setStartOffset(1000);
//持续2s
animation.setDuration(2000);
//最终还原
animation.setFillBefore(true);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 1.2 xml实现: 缩放动画
* <scale>
*/
/*
1. 定义动画文件
2. 加载动画文件得到动画对象
3. 启动动画
*/
public void startXmlScale(View v) {
tv_animation_msg.setText("Xml缩放动画: Xml缩放动画: 宽度从0.0到1.5, 高度从0.0到1.0, 延迟1s开始,持续3s,圆心为右下角, 最终固定");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 2.1 编码实现: 旋转动画
* RotateAnimation
*/
public void startCodeRotate(View v) {
tv_animation_msg.setText("Code旋转动画: 以图片中心点为中心, 从负90度到正90度, 持续5s");
//1. 创建动画对象
RotateAnimation animation = new RotateAnimation(-90, 90, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//2. 设置
animation.setDuration(5000);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 2.2 xml实现: 旋转动画
* <rotate>
*/
public void startXmlRotate(View v) {
tv_animation_msg.setText("Xml旋转动画: 以左顶点为坐标, 从正90度到负90度, 持续5s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 3.1 编码实现: 透明度动画
* 完全透明 : 0
* 完全不透明 : 1
* AlphaAnimation
*/
public void startCodeAlpha(View v) {
tv_animation_msg.setText("Code透明度动画: 从完全透明到完全不透明, 持续2s");
//1. 创建动画对象
AlphaAnimation animation = new AlphaAnimation(0, 1);
// 2. 设置
animation.setDuration(4000);
// 3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 3.2 xml实现: 透明度动画
* <alpha>
*/
public void startXmlAlpha(View v) {
tv_animation_msg.setText("Xml透明度动画: 从完全不透明到完全透明, 持续4s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_test);
animation.setFillAfter(true);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 4.1 编码实现: 平移动画
* TranslateAnimation
*/
public void startCodeTranslate(View v) {
tv_animation_msg.setText("Code移动动画: 向右移动一个自己的宽度, 向下移动一个自己的高度, 持续2s");
//1. 创建动画对象
TranslateAnimation animation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 1, Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 1);
//2. 设置
animation.setDuration(2000);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 4.2 xml实现: 平移动画
* <translate>
*/
public void startXmlTranslate(View v) {
tv_animation_msg.setText("xml移动动画: 从屏幕的右边逐渐回到原来的位置, 持续2s"); //***此效果用于界面切换的动画效果
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 5.1 编码实现: 复合动画
* AnimationSet
*/
public void startCodeAnimationSet(View v) {
tv_animation_msg.setText("Code复合动画: 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续1s");
//1. 创建透明动画并设置
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(2000);
//2. 创建旋转动画并设置
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(1000);
rotateAnimation.setStartOffset(2000);//延迟
//3. 创建复合动画对象
AnimationSet animationSet = new AnimationSet(true);
//4. 添加两个动画
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
//5. 启动复合动画对象
iv_animation.startAnimation(animationSet);
}
/*
* 5.2 xml实现: 复合动画
* <set>
*/
public void startXmlAnimationSet(View v) {
tv_animation_msg.setText("Xml复合动画: 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续2s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.set_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
/*
* 6. 测试动画监听
*/
public void testAnimationListener(View v) {
tv_animation_msg.setText("测试动画监听");
//tv_animation_msg.setText("Xml旋转动画: 以左顶点为坐标, 从正90度到负90度, 持续5s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(1000);
//设置线性变化
animation.setInterpolator(new LinearInterpolator());
//设置动画重复次数
animation.setRepeatCount(Animation.INFINITE);//重复3次
//设置动画监听
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.e("TAG", "动画开始");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.e("TAG", "动画重复");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.e("TAG", "动画结束");
}
});
//3. 启动动画
iv_animation.startAnimation(animation);
}
}
运行效果如图如下:
4.2逐帧动画
Activity的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_da_mm"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="160dp"
android:background="@drawable/drawable_animation_test"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
<Button
android:id="@+id/btn_da_start"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="启动动画" />
<Button
android:id="@+id/btn_da_stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="结束动画" />
</LinearLayout>
</RelativeLayout>
动画文件:
drawable_animation_test.xml
<?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/nv1"
android:duration="500"/>
<item
android:drawable="@drawable/nv2"
android:duration="500"/>
<item
android:drawable="@drawable/nv3"
android:duration="500"/>
<item
android:drawable="@drawable/nv4"
android:duration="500">
</item>
</animation-list>
主Activity:
/**
* 测试: Drawable Animation
* Created by quguangle on 2016/12/1.
*/
public class DAActivity extends Activity implements View.OnClickListener {
private ImageView iv_da_mm;
private Button btn_da_start;
private Button btn_da_stop;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation_da);
iv_da_mm = (ImageView) findViewById(R.id.iv_da_mm);
btn_da_start = (Button) findViewById(R.id.btn_da_start);
btn_da_stop = (Button) findViewById(R.id.btn_da_stop);
btn_da_start.setOnClickListener(this);
btn_da_stop.setOnClickListener(this);
}
private AnimationDrawable animationDrawable;
@Override
public void onClick(View v) {
if (v == btn_da_start) {
if(animationDrawable==null) {
//得到背景动画图片对象
animationDrawable = (AnimationDrawable) iv_da_mm.getBackground();
//启动
animationDrawable.start();
}
} else if (v == btn_da_stop) {
if(animationDrawable!=null) {
animationDrawable.stop();
animationDrawable = null;
}
}
}
}
运行效果如下:
5.View Animation
- 单一动画(Animation)
- 缩放动画(ScaleAnimation)
- 透明度动画(AlphaAnimation)
- 旋转动画(RotateAnimation)
- 平移动画(TranslateAnimation)
- 复合动画(AnimationSet)
- 由多个单一动画组合在一起的动画
补间动画的视图结构:
5.1如何使用View Animation
Animation的公用功能:
•setDuration(long durationMillis) : 设置持续时间(单位ms)
•setStartOffset(long startOffset) : 设置开始的延迟的时间(单位ms)
•setFillBefore(boolean fillBefore) : 设置最终是否固定在起始状态
•setFillAfter(boolean fillAfter) : 设置最终是否固定在最后的状态
•setAnimationListener(AnimationListener listener) : 设置动画监听
•坐标类型:
•Animation.ABSOLUTE
•Animation.RELATIVE_TO_SELF
•Animation.RELATIVE_TO_PARENT
•启动动画 : view.startAnimation(animation);
•结束动画: view.clearAnimation()
•动画监听器 : AnimationListener
•onAnimationStart(Animation animation) : 动画开始的回调
•onAnimationEnd(Animation animation) : 动画结束的回调
•onAnimationRepeat(Animation animation) : 动画重复执行
1.》缩放动画(Code ScaleAnimation)
•fromX : 开始时X轴上的缩放比例
•toX : 结束时X轴上的缩放比例
•fromY :开始时Y轴上的缩放比例
•toY :结束时Y轴上的缩放比例
•pivotXType : X轴坐标的类型(计算x轴上的偏移量的方式)
•pivotXVlaue : 中心点在X轴相对视图左顶点在x轴上的偏移量
•pivotYType : Y轴坐标的类型(计算x轴上的偏移量的方式)
•pivotYValue : 中心点相对视图左顶点在y轴上的偏移量
2.》缩放动画(Xml ScaleAnimation)
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX=“1"
android:pivotY=“0.5“
android:toXScale="1.0"
android:toYScale="1.0"
android:fillAfter="true"/>
•Animation.ABSOLUTE :
数值(默认以px为单位) 100
•Animation.RELATIVE_TO_SELF :
百分数,如:50% (以当前视图的宽度或高度其为基数来计算)
•Animation.RELATIVE_TO_PARENT :
百分数+p,如:50%p (以父视图的宽度或高度其为基数来计算)
3》旋转动画(RotateAnimation)
•fromDegrees : 开始时的角度
•toDegrees : 结束时的角度
•pivotXType : X轴坐标的类型
•pivotXVlaue : X轴坐标的值
•pivotYType : Y轴坐标的类型
•pivotYValue : Y轴坐标的值
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromDegrees="+90“
android:toDegrees="-90"
android:pivotX="0%"
android:pivotY="0%"/>
4.》透明度动画(AlphaAnimation)
•fromAlpha : 开始时的缩放比例
•toAlpha : 结束时的缩放比例
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:startOffset="500"
android:duration="1000" />
5.》平移动画(TranslateAnimation)
•fromXType : 坐标类型
•fromXValue : 开始时X轴的坐标
•toXType :坐标类型
•toXValue : 结束时X轴的坐标
•fromYType :坐标类型
•fromYValue : 开始时Y轴的坐标
•toYType :坐标类型
•toYValue : 结束时Y轴的坐标
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="-100%p"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
6.复合动画(Code AnimationSet)
// 复合动画对象
AnimationSet animationSet = new AnimationSet(false);
// 添加一个单一动画
animationSet.addAnimation(alpha);
animationSet.addAnimation(rotate);
//开启动画
iv_animation.startAnimation(animationSet);
6.1复合动画(Xml AnimationSet)
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="2000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%“
android:toDegrees="360" />
</set>
7.Interpolator属性的使用(这里我们稍微提一下,后面我还要详细的讲解)
Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复)等。
•@android:anim/linear_interpolator : 线性变化
•@android:anim/accelerate_interpolator : 加速变化
•@android:anim/decelerate_interpolator : 减速变化
•@android:anim/cycle_interpolator : 周期循环变化
8.如何使用Drawable Animation
8.1动画配置
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/nv1" android:duration="500" />
<item android:drawable="@drawable/nv2" android:duration="500" />
<item android:drawable="@drawable/nv3" android:duration="500" />
<item android:drawable="@drawable/nv4" android:duration="500" />
</animation-list>
<ImageView
android:id="@+id/iv_dv"
android:layout_width=“80dp"
android:layout_height=“80dp"
android:layout_marginTop="160dp"
android:background="@drawable/anim_da" />
8.2启动Drawable动画
//得到背景动画图上
AnimationDrawable ad = null;
ad = (AnimationDrawable) imageView.getBackground();
//启动动画
ad.start();
//停止动画
ad.stop();
到此所用的逐帧动画和补间动画的基本使用我们都讲完了,下面我们将给出具体的应用例子