Android:动画的理解和使用(帧动画(Frame Animation),补间动画(Tweened Animation))

1、动画的理解和使用

Android 动画分类

总的来说,Android动画可以分为两类,最初的传统动画和Android3.0 之后出现的属性动画;传统动画又包括 帧动画(Frame Animation)补间动画(Tweened Animation)

1.1、逐帧动画

1.1.1、 定义

帧动画是最容易实现的一种动画,这种动画更多的依赖于完善的UI资源,他的原理就是将一张张单独的图片连贯的进行播放,从而在视觉上产生一种动画的效果;有点类似于某些软件制作gif动画的方式。

  • 帧动画是顺序播放一组预先定义好的图片,不同于动画,系统提供了另外一个类AnimationDrawable来使用帧动画。

在这里插入图片描述

1.1.2、 使用方式

方式1

  • 1、准备图片资源:将图片资源放在drawable-hdpi目录下;

  • 2、在drawable目录下新建animation-list类型文件:frame_anim.xml

  • 3、在布局文件中,添加ImageView,将其background属性设置为动画资源xml:activity_main.xml

    • 也可以在代码中动态设置
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/frame_anim" />
  • 4、java中,获取动画资源,调用start( )开启动画,stop( )停止动画

frame_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true" >
 
    <!-- animation-list 帧动画 -->
    <!-- android:oneshot的值为 false代表播放多次,true代表只播放一次 -->
    <!-- duration代表每张图片的播放时间 ,定义一个持续时间为50毫秒的动画帧 -->
    <item
        android:drawable="@drawable/img00"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img01"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img02"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img03"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img04"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img05"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img06"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img07"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img08"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img09"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img10"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img11"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img12"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img13"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img14"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img15"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img16"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img17"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img18"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img19"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img20"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img21"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img22"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img23"
        android:duration="50"/>
    <item
        android:drawable="@drawable/img24"
        android:duration="50"/>
 
</animation-list>

根节点是animation-list(动画列表),里面有一个或者多个item节点组成,oneshot属性表示是否只播放一次,true表示只会播放一次,false表示一直循环播放,内部用item节点声明一个动画帧,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒

在activity_main中添加控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.havorld.frameanimation.MainActivity" >
 
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
    <!-- android:background="@drawable/frame_anim" -->
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:padding="10dp" >
 
        <Button
            android:id="@+id/start"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="播放" />
 
        <Button
            android:id="@+id/stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="停止" />
    </LinearLayout>
 
</RelativeLayout>

在代码中获取并开启帧动画

public class MainActivity extends Activity implements OnClickListener {
 
	private ImageView imageView;
	private AnimationDrawable animationDrawable;
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
 
		imageView = (ImageView) findViewById(R.id.imageView);
		findViewById(R.id.start).setOnClickListener(this);
		findViewById(R.id.stop).setOnClickListener(this);
 
		setXml2FrameAnim1();
		// setXml2FrameAnim2();
 
	}
 
	/**
	 * 通过XML添加帧动画方法一
	 */
	private void setXml2FrameAnim1() {
 
		// 把动画资源设置为imageView的背景,也可直接在XML里面设置
		imageView.setBackgroundResource(R.drawable.frame_anim);
		animationDrawable = (AnimationDrawable) imageView.getBackground();
	}
 
	/**
	 * 通过XML添加帧动画方法二
	 */
	private void setXml2FrameAnim2() {
 
		// 通过逐帧动画的资源文件获得AnimationDrawable示例
		animationDrawable = (AnimationDrawable) getResources().getDrawable(
				R.drawable.frame_anim);
		imageView.setBackground(animationDrawable);
	}
 
	@Override
	public void onClick(View v) {
 
		switch (v.getId()) {
		case R.id.start:
			if (animationDrawable != null && !animationDrawable.isRunning()) {
				animationDrawable.start();
			}
			break;
		case R.id.stop:
			if (animationDrawable != null && animationDrawable.isRunning()) {
				animationDrawable.stop();
			}
			break;
 
		default:
			break;
		}
	}
 
}

AnimationDrawable 几个常见的api

void start() - 开始播放动画

void stop() - 停止播放动画

addFrame(Drawable frame, int duration) - 添加一帧,并设置该帧显示的持续时间

void setOneShoe(boolean flag) - false为循环播放,true为仅播放一次

boolean isRunning() - 是否正在播放

方式2

通过代码实现帧动画

	/**
	 * 通过代码添加帧动画方法
	 */
	private void setSrc2FrameAnim() {
 
		animationDrawable = new AnimationDrawable();
		// 为AnimationDrawable添加动画帧
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img00), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img01), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img02), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img03), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img04), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img05), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img06), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img07), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img08), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img09), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img10), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img11), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img12), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img13), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img14), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img15), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img16), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img17), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img18), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img19), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img20), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img21), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img22), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img23), 50);
		animationDrawable.addFrame(
				getResources().getDrawable(R.drawable.img24), 50);
		// 设置为循环播放
		animationDrawable.setOneShot(false);
		imageView.setBackground(animationDrawable);
	}


代码

1.2、补间动画(Tweened Animation)

在这里插入图片描述

1.2.1、 定义

和前面学的帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!

  • 原形态变成新形态时为了过渡变形过程,生成的动画就叫补间动画

补间动画的使用方式分为两种:在XML 代码 / Java 代码里设置

  • 前者优点:动画描述的可读性更好
  • 后者优点:动画效果可动态创建

1.2.2、补间动画的分类

根据不同的动画效果,补间动画分为4种动画:

  • 平移动画(Translate)
  • 缩放动画(scale)
  • 旋转动画(rotate)
  • 透明度动画(alpha)

同时,不同类型的动画对应于不同的子类,具体如下图:
在这里插入图片描述
具体说明如下:

  • 1、AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应标签!
  • 2、ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点,还有动画的持续时间;对应标签!
  • 3、TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续时间即可;对应标签!
  • 4、RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画持续时间和旋转的轴心;对应标签
  • 5、AnimationSet:组合渐变,就是前面多种渐变的组合,对应标签

1.2.3、平移动画(Translate)

在这里插入图片描述
设置方法1:在XML 代码中设置

  • 步骤1:在 res/anim的文件夹里创建动画效果.xml文件

此处路径为res/anim/translate.xml

  • 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:

部分参数说明

<?xml version="1.0" encoding="utf-8"?>
// 采用<translate /> 标签表示平移动画
<translate xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是平移动画特有的属性
    android:fromXDelta="0" // 视图在水平方向x 移动的起始值
    android:toXDelta="500" // 视图在水平方向x 移动的结束值

    android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
    android:toYDelta="500" // 视图在竖直方向y 移动的结束值

    /> 


在这里插入图片描述
注①: 数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点

  • 骤3:在Java代码中创建Animation对象并播放动画
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View
        Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
        // 步骤2:创建 动画对象 并传入设置的动画效果xml文件
        mButton.startAnimation(translateAnimation);
        // 步骤3:播放动画

简单使用demo:

translate.xml

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

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是动画" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;



public class MainActivity extends AppCompatActivity {

    private static final  String TAG = "jmw";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this
                        ,R.anim.translate);
                button.startAnimation(animation);
            }
        });

    }


}

实验效果:
在这里插入图片描述

设置方法2:在 Java 代码中设置

        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View

        Animation translateAnimation = new TranslateAnimation(0,500,0,500);
        // 步骤2:创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
        // 参数分别是:
        // 1. fromXDelta :视图在水平方向x 移动的起始值
        // 2. toXDelta :视图在水平方向x 移动的结束值
        // 3. fromYDelta :视图在竖直方向y 移动的起始值
        // 4. toYDelta:视图在竖直方向y 移动的结束值

        translateAnimation.setDuration(3000);
        // 固定属性的设置都是在其属性前加“set”,如setDuration()
        mButton.startAnimation(translateAnimation);
        // 步骤3:播放动画

1.2.4、缩放动画(Scale)

在这里插入图片描述
设置方法1:在XML 代码中设置

  • 步骤1:在 res/anim的文件夹里创建动画效果.xml文件

此处路径为res/anim/scale.xml

  • 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:

部分参数说明

<?xml version="1.0" encoding="utf-8"?>
// 采用<scale/> 标签表示是缩放动画
<scale  xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是缩放动画特有的属性
    android:fromXScale="0.0" 
    // 动画在水平方向X的起始缩放倍数
    // 0.0表示收缩到没有;1.0表示正常无伸缩
    // 值小于1.0表示收缩;值大于1.0表示放大

    android:toXScale="2"  //动画在水平方向X的结束缩放倍数

    android:fromYScale="0.0" //动画开始前在竖直方向Y的起始缩放倍数
    android:toYScale="2" //动画在竖直方向Y的结束缩放倍数

    android:pivotX="50%" // 缩放轴点的x坐标
    android:pivotY="50%" // 缩放轴点的y坐标
    // 轴点 = 视图缩放的中心点

    // pivotX pivotY,可取值为数字,百分比,或者百分比p
    // 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
    // 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。
    //在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
    // 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。
    //在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT

    // 两个50%表示动画从自身中间开始,具体如下图

    /> 

在这里插入图片描述

pivot 这个属性主要是在translate 和 scale 动画中,这两种动画都牵扯到view 的“物理位置“发生变化,所以需要一个参考点。而pivotX和pivotY就共同决定了这个点;它的值可以是float或者是百分比数值。

以pivotX为例,

pivotX取值含义
10距离动画所在view自身左边缘10像素
10%距离动画所在view自身左边缘 的距离是整个view宽度的10%
10%p距离动画所在view父控件左边缘的距离是整个view宽度的10%

pivotY 也是相同的原理,只不过变成的纵向的位置。如果还是不明白可以参考源码,在Tweened Animation中结合seekbar的滑动观察rotate的变化理解。

在这里插入图片描述

在这里插入图片描述
步骤3:在Java代码中创建Animation对象并播放动画


        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View
        Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
        // 步骤2:创建 动画对象 并传入设置的动画效果xml文件
        mButton.startAnimation(scaleAnimation);
        // 步骤3:播放动画

简单使用demo:

scale.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:fromXScale="1"
        android:fromYScale="1"
        android:toXScale="0.5"
        android:toYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000" />
</set>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是动画" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;



public class MainActivity extends AppCompatActivity {

    private static final  String TAG = "jmw";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView imageView = findViewById(R.id.iv);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过加载xml动画设置文件来创建一个Animataion对象
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this
                        ,R.anim.scale);
                imageView.startAnimation(animation);
            }
        });

    }


}

下面展示轴点为(50%,50%) 的情况
在这里插入图片描述

设置方法2:在 Java 代码中设置

        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View

          Animation rotateAnimation = new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        // 步骤2:创建缩放动画的对象 & 设置动画效果:缩放动画对应的Animation子类为RotateAnimation
        // 参数说明:
        // 1. fromX :动画在水平方向X的结束缩放倍数
        // 2. toX :动画在水平方向X的结束缩放倍数
        // 3. fromY :动画开始前在竖直方向Y的起始缩放倍数
        // 4. toY:动画在竖直方向Y的结束缩放倍数
        // 5. pivotXType:缩放轴点的x坐标的模式
        // 6. pivotXValue:缩放轴点x坐标的相对值
        // 7. pivotYType:缩放轴点的y坐标的模式
        // 8. pivotYValue:缩放轴点y坐标的相对值

        // pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)


        scaleAnimation.setDuration(3000);
        // 固定属性的设置都是在其属性前加“set”,如setDuration()

        mButton.startAnimation(scaleAnimation);
        // 步骤3:播放动画


1.2.5、旋转动画(Rotate)

在这里插入图片描述

设置方法1:在XML 代码中设置

  • 步骤1:在 res/anim的文件夹里创建动画效果.xml文件

此处路径为res/anim/rotate.xml

  • 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:

部分参数说明

<?xml version="1.0" encoding="utf-8"?>
// 采用<rotate/> 标签表示是旋转动画
<rotate xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是旋转动画特有的属性
    android:duration="1000"
    android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:toDegrees="270" // 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:pivotX="50%" // 旋转轴点的x坐标
    android:pivotY="0" // 旋转轴点的y坐标
    // 轴点 = 视图缩放的中心点

// pivotX pivotY,可取值为数字,百分比,或者百分比p
    // 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。
   		 //在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
    // 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。
   		 //在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
    // 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。
   		 //在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
    // 两个50%表示动画从自身中间开始,具体如下图

    /> 

在这里插入图片描述

  • 骤3:在Java代码中创建Animation对象并播放动画
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View
        Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
        // 步骤2:创建 动画对象 并传入设置的动画效果xml文件
        mButton.startAnimation(translateAnimation);
        // 步骤3:播放动画

简单使用demo:

rotate.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000" />
</set>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是动画" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;



public class MainActivity extends AppCompatActivity {

    private static final  String TAG = "jmw";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this
                        ,R.anim.rotate);
                button.startAnimation(animation);
            }
        });

    }


}

实验效果:
在这里插入图片描述

设置方法2:在 Java 代码中设置

               Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View

          Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        // 步骤2:创建旋转动画的对象 & 设置动画效果:旋转动画对应的Animation子类为RotateAnimation
        // 参数说明:
        // 1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        // 2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
        // 3. pivotXType:旋转轴点的x坐标的模式
        // 4. pivotXValue:旋转轴点x坐标的相对值
        // 5. pivotYType:旋转轴点的y坐标的模式
        // 6. pivotYValue:旋转轴点y坐标的相对值

        // pivotXType = Animation.ABSOLUTE:旋转轴点的x坐标 =  View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_SELF:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
        // pivotXType = Animation.RELATIVE_TO_PARENT:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)


        rotateAnimation.setDuration(3000);
        // 固定属性的设置都是在其属性前加“set”,如setDuration()

        mButton.startAnimation(rotateAnimation);
        // 步骤3:播放动画

1.2.6、透明度动画(Alpha)

在这里插入图片描述

设置方法1:在XML 代码中设置

  • 步骤1:在 res/anim的文件夹里创建动画效果.xml文件

此处路径为res/anim/alpha.xml

  • 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:

部分参数说明

<?xml version="1.0" encoding="utf-8"?>
// 采用<alpha/> 标签表示是透明度动画
<alpha xmlns:android="http://schemas.android.com/apk/res/android"

    // 以下参数是4种动画效果的公共属性,即都有的属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
    // 以下参数是透明度动画特有的属性
    android:fromAlpha="1.0" // 动画开始时视图的透明度(取值范围: -1 ~ 1)
    android:toAlpha="0.0"// 动画结束时视图的透明度(取值范围: -1 ~ 1)

    /> 

在这里插入图片描述

  • 骤3:在Java代码中创建Animation对象并播放动画
        Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View
        Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
        // 步骤2:创建 动画对象 并传入设置的动画效果xml文件
        mButton.startAnimation(alphaAnimation);
        // 步骤3:播放动画

简单使用demo:

alpha.xml

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

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是动画" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;



public class MainActivity extends AppCompatActivity {

    private static final  String TAG = "jmw";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this
                        ,R.anim.alpha);
                button.startAnimation(animation);
            }
        });

    }


}

实验效果:
在这里插入图片描述

设置方法2:在 Java 代码中设置

      Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View

      Animation alphaAnimation = new AlphaAnimation(1,0);
        // 步骤2:创建透明度动画的对象 & 设置动画效果:透明度动画对应的Animation子类为AlphaAnimation
        // 参数说明:
        // 1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
        // 2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)


        alphaAnimation.setDuration(3000);
        // 固定属性的设置都是在其属性前加“set”,如setDuration()

        mButton.startAnimation(alphaAnimation);
        // 步骤3:播放动画

1.2.7、组合动画

在这里插入图片描述

设置方法1:在XML 代码中设置

  • 步骤1:在 res/anim的文件夹里创建动画效果.xml文件

此处路径为res/anim/conbined_view.xml

  • 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:

部分参数说明

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

// 组合动画同样具备公共属性
    android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
    android:startOffset ="1000" // 动画延迟开始时间(ms)
    android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
    android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
    android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
    
// 组合动画独特的属性
    android:shareinterpolator = “true”
    // 表示组合动画中的动画是否和集合共享同一个差值器
    // 如果集合不指定插值器,那么子动画需要单独设置

// 组合动画播放时是全部动画同时开始
// 如果想不同动画不同时间开始就要使用android:startOffset属性来延迟单个动画播放时间

// 设置旋转动画,语法同单个动画
    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatMode="restart"
        android:repeatCount="infinite"
        />

// 设置平移动画,语法同单个动画
    <translate
        android:duration="10000"
        android:startOffset = “1000”// 延迟该动画播放时间
        android:fromXDelta="-50%p"
        android:fromYDelta="0"
        android:toXDelta="50%p"
        android:toYDelta="0" />

// 设置透明度动画,语法同单个动画
    <alpha
        android:startOffset="7000"
        android:duration="3000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />


// 设置缩放动画,语法同单个动画
    <scale
        android:startOffset="4000"
        android:duration="1000"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.5"
        android:toYScale="0.5" />
// 特别注意:
// 1. 在组合动画里scale缩放动画设置的repeatCount(重复播放)和fillBefore(播放完后,视图是否会停留在动画开始的状态)是无效的。
// 2. 所以如果需要重复播放或者回到原位的话需要在set标签里设置
// 3. 但是由于此处rotate旋转动画里已设置repeatCount为infinite,所以动画不会结束,也就看不到重播和回复原位

</set>

  • 骤3:在Java代码中创建Animation对象并播放动画
       Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View
        Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
        // 步骤2:创建 动画对象 并传入设置的动画效果xml文件
        mButton.startAnimation(translateAnimation);
        // 步骤3:播放动画

简单使用demo:

conbined_view.xml

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

    android:duration="3000"
    android:startOffset ="1000"
    android:fillBefore = “true”
    android:fillAfter = “false”
    android:fillEnabled= “true”
    android:repeatMode= “restart”
    android:repeatCount = “0”
    android:interpolator = @[package:]anim/interpolator_resource

    android:shareinterpolator = “true”

    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatMode="restart"
        android:repeatCount="infinite" />

    <translate
        android:duration="10000"
        android:startOffset ="1000"
        android:fromXDelta="-50%p"
        android:fromYDelta="0"
        android:toXDelta="50%p"
        android:toYDelta="0" />

    <alpha
        android:startOffset="7000"
        android:duration="3000"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />

    <scale
        android:startOffset="4000"
        android:duration="1000"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.5"
        android:toYScale="0.5" />
</set>


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是动画" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;



public class MainActivity extends AppCompatActivity {

    private static final  String TAG = "jmw";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this
                        ,R.anim.conbined_view);
                button.startAnimation(animation);
            }
        });

    }


}

实验效果:

在这里插入图片描述

设置方法2:在 Java 代码中设置

   
Button mButton = (Button) findViewById(R.id.Button);
        // 创建 需要设置动画的 视图View

        // 组合动画设置
        AnimationSet setAnimation = new AnimationSet(true);
        // 步骤1:创建组合动画对象(设置为true)


        // 步骤2:设置组合动画的属性
        // 特别说明以下情况
        // 因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
        // 所以动画不会结束,而是无限循环
        // 所以组合动画的下面两行设置是无效的
        setAnimation.setRepeatMode(Animation.RESTART);
        setAnimation.setRepeatCount(1);// 设置了循环一次,但无效

        // 步骤3:逐个创建子动画(方式同单个动画创建方式,此处不作过多描述)

        // 子动画1:旋转动画
        Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        rotate.setDuration(1000);
        rotate.setRepeatMode(Animation.RESTART);
        rotate.setRepeatCount(Animation.INFINITE);

        // 子动画2:平移动画
        Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
                TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
                TranslateAnimation.RELATIVE_TO_SELF,0
                ,TranslateAnimation.RELATIVE_TO_SELF,0);
        translate.setDuration(10000);

        // 子动画3:透明度动画
        Animation alpha = new AlphaAnimation(1,0);
        alpha.setDuration(3000);
        alpha.setStartOffset(7000);

        // 子动画4:缩放动画
        Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        scale1.setDuration(1000);
        scale1.setStartOffset(4000);

        // 步骤4:将创建的子动画添加到组合动画里
        setAnimation.addAnimation(alpha);
        setAnimation.addAnimation(rotate);
        setAnimation.addAnimation(translate);
        setAnimation.addAnimation(scale1);

        mButton.startAnimation(setAnimation);
        // 步骤5:播放动画

1.2.8、综合案例

conbined_view.xml alpha.xm rotate.xml scale.xml translate.xml 同上面各小结案例

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_alpha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="透明度渐变" />

    <Button
        android:id="@+id/btn_scale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="缩放渐变" />

    <Button
        android:id="@+id/btn_tran"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位移渐变" />

    <Button
        android:id="@+id/btn_rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="旋转渐变" />

    <Button
        android:id="@+id/btn_set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="组合渐变" />

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        android:src="@mipmap/img_face" />

</LinearLayout>

MainActivity

package com.example.buttontes;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_alpha;
    private Button btn_scale;
    private Button btn_tran;
    private Button btn_rotate;
    private Button btn_set;
    private ImageView img_show;
    private Animation animation = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        btn_alpha = (Button) findViewById(R.id.btn_alpha);
        btn_scale = (Button) findViewById(R.id.btn_scale);
        btn_tran = (Button) findViewById(R.id.btn_tran);
        btn_rotate = (Button) findViewById(R.id.btn_rotate);
        btn_set = (Button) findViewById(R.id.btn_set);
        img_show = (ImageView) findViewById(R.id.img_show);

        btn_alpha.setOnClickListener(this);
        btn_scale.setOnClickListener(this);
        btn_tran.setOnClickListener(this);
        btn_rotate.setOnClickListener(this);
        btn_set.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_alpha:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.alpha);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_scale:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.scale);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_tran:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.translate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_rotate:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.rotate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_set:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.conbined_view);
                img_show.startAnimation(animation);
                break;
        }
    }
}

在这里插入图片描述

参考

1、https://www.jianshu.com/p/16e0d4e92bb2
2、https://www.jianshu.com/p/420629118c10
3、https://blog.csdn.net/carson_ho/article/details/72827747
4、https://www.runoob.com/w3cnote/android-tutorial-alphaanimation.html
5、https://blog.csdn.net/m0_37796683/article/details/90607428?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
6、https://www.jianshu.com/p/2f19fe1e3ca1

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值