动画【Android】

本文详细介绍了Android中的动画实现方式,包括View Animation和Drawable Animation。讲解了动画的分类,如缩放、透明度、旋转和平移,以及如何通过代码和XML配置创建动画。此外,还提到了AnimationSet用于组合多个单一动画,以及相关API的使用,如设置动画监听、动画的开始、结束和重复回调。最后,文章探讨了Interpolator如何改变动画效果,并给出了启动和停止动画的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、关于动画

动画有下面两种情况

同一个图形通过视图在界面上进行透明度,缩放,旋转,平移的变化(View动画)

在界面的同一个位置上不断切换显示不同的图片(Drawable动画)

动画的分类

View Animation

Drawable Animation

Android中提供了两种实现动画的方式

纯编码的方式

Xml配置的方式

动画在应用中是非常常见的界面效果, 也是提高用户体验的一种好手段

二、动画的分类

单一动画(Animation)

缩放动画(ScaleAnimation)

透明度动画(AlphaAnimation)

旋转动画(RotateAnimation)

平移动画(TranslateAnimation)

复合动画(AnimationSet)

由多个单一动画组合在一起的动画

三、相关API

1.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) : 动画重复执行

2.缩放动画(Code ScaleAnimation)

ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
fromX : 开始时X轴上的缩放比例   
toX : 结束时X轴上的缩放比例   
fromY :开始时Y轴上的缩放比例
toY :结束时Y轴上的缩放比例


pivotXType : X轴坐标的类型(计算x轴上的偏移量的方式)
pivotXVlaue : 中心点在X轴相对视图左顶点在x轴上的偏移量
pivotYType :  Y轴坐标的类型(计算x轴上的偏移量的方式)
pivotYValue : 中心点相对视图左顶点在y轴上的偏移量

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0"
    android:fromYScale="0"
    android:toXScale="1.5"
    android:toYScale="1" 
    android:startOffset="1000"
    android:duration="3000"
    android:pivotX="100%"
    android:pivotY="100%"
    android:fillAfter="true">

</scale>
<!-- 宽度从0.0到1.5, 高度从0.0到1.0, 延迟1s开始,持续3s,圆心为右下角, 最终固定 -->
3.旋转动画(RotateAnimation)

RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue);
fromDegrees : 开始时的角度
toDegrees : 结束时的角度


pivotXType : X轴坐标的类型
pivotXVlaue : X轴坐标的值
pivotYType :  Y轴坐标的类型
pivotYValue : Y轴坐标的值

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90" 
    android:toDegrees="-90"
    android:duration="5000">
    
</rotate>
<!-- 以左顶点为坐标, 从正90度到负90度, 持续5s -->

4.透明度动画(AlphaAnimation)

AlphaAnimation(fromAlpha, toAlpha);
fromAlpha : 开始时的缩放比例
toAlpha : 结束时的缩放比例

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1" 
    android:toAlpha="0"
    android:duration="4000">

</alpha>
<!-- 从完全不透明到完全透明, 持续4s -->


5.平移动画(TranslateAnimation)

TranslateAnimation(fromXType, fromXValue, toXType, toXValue, fromYType, fromYValue, toYType, toYValue);
fromXType : 坐标类型
fromXValue : 开始时X轴的坐标
toXType :坐标类型
toXValue : 结束时X轴的坐标
fromYType :坐标类型
fromYValue : 开始时Y轴的坐标
toYType :坐标类型
toYValue : 结束时Y轴的坐标

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%p" 
    android:toXDelta="0"
    android:fromYDelta="0"
    android:toYDelta="0"
    android:duration="2000">
    

</translate>
<!-- 从屏幕的右边逐渐回到原来的位置, 持续2s -->


6.复合动画(Code AnimationSet)

// 复合动画对象
AnimationSet animationSet = new AnimationSet(false);

// 添加一个单一动画
animationSet.addAnimation(alpha);
animationSet.addAnimation(rotate);

//开启动画
iv_animation.startAnimation(animationSet);

复合动画(Xml AnimationSet):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <alpha
        android:duration="2000"
        android:fromAlpha="0"
        android:toAlpha="1" >
    </alpha>

    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:startOffset="2000"
        android:toDegrees="360" />

</set>
<!-- 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续2s -->

7.Interpolator属性的使用

Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复)等。


@android:anim/linear_interpolator  : 线性变化


@android:anim/accelerate_interpolator  : 加速变化


@android:anim/decelerate_interpolator  : 减速变化


@android:anim/cycle_interpolator : 周期循环变化

8.动画监听
在程序中可以对动画的特定时刻进行监听
Animation.setAnimationListener(AnimationListener listener) : 设置动画监听


动画监听器 : AnimationListener
onAnimationStart(Animation animation) : 动画开始的回调
onAnimationEnd(Animation animation) : 动画结束的回调
onAnimationRepeat(Animation animation) : 动画重复执行

9.动画配置

<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" />
10.启动Drawable动画

//得到背景动画图上
AnimationDrawable ad = null;
ad = (AnimationDrawable) imageView.getBackground();


//启动动画
ad.start();


//停止动画
ad.stop();
四、代码实现:

package com.atguigu.l10_animation;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

/*
 * 编码实现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 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);
		
	}
}
package com.atguigu.l10_animation;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

/*
 * 测试: Drawable Animation
 */
public class DAActivity extends Activity implements 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;
			}
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值