Android学习|动画——逐帧、补间、属性动画

Android学习|动画

    • 一、动画分类
      • 1、逐帧动画
        • 演示
      • 2、补间动画 (补帧)
        • 2.1 类型
          • 1、 alpha 透明度 Demo
          • 2.、rotate 旋转 Demo
          • 3、scale 缩放 Demo
          • 4、 translate 平移 Demo
        • 2.2 Java代码中设置动画绑定
        • 2.3、ctivity_main.xml中的代码
      • 3.属性动画
      • 1、ValueAnimator
      • 2、ObjectAnimator
        • 监听器

一、动画分类

Android动画按照不同类型分为以下几种:

1.逐帧动画(frame-by-frame animation) : 几张图片进行快速的播放形成的动画
2.补间动画(tweened animation):设置初始值、结束值。中间动态由安卓完成
3.属性动画(property animation):对组件的属性进行改变,从而达到动画的效果

    逐帧就是图片叠加显示效果。补间动画与属性动画有些相似,区别在于补间动画可操作属性较少,并且需要java、xml配合,属性动画对属性都能操作,java即可完成

1、逐帧动画

逐帧动画(frame-by-frame animation) : 几张图片进行快速的播放形成的动画

实现逻辑:drawable下创建xml资源,通过animation-list形成动画,然后设置成一个布局(例如RelativeLayout)的背景。再通过java代码获取到动画的 Drawable资源,然后通过其start() 启动动画stop()停止动画,可配合点击事件完成。


演示

1.1.1、drawable下创建frame.xml,添加animation-list,animation-list添加图片。
参数:duration:一张图片显示的多少毫秒


<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/frame1" android:duration="120">item>
    <item android:drawable="@drawable/frame2" android:duration="120">item>
    <item android:drawable="@drawable/frame3" android:duration="120">item>
    <item android:drawable="@drawable/frame4" android:duration="120">item>
    <item android:drawable="@drawable/frame5" android:duration="120">item>
    <item android:drawable="@drawable/frame6" android:duration="120">item>
    <item android:drawable="@drawable/frame7" android:duration="120">item>
    <item android:drawable="@drawable/frame8" android:duration="120">item>
animation-list>

1.1.2、activity_main.xml中设置刚才的feame为background(此处使用的是RelativeLayout布局)


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/frame">


RelativeLayout>

1.1.2、动画的启动和停止

a、获取动画的 Drawable资源
AnimationDrawable anim = (AnimationDrawable) relativeLayout.getBackground();

b、启动动画 :anim.start();

c、 停止动画 :anim.stop();

package com.example.thriddemo_animation_1;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {

    private boolean flag = true;   // 动画是否停止

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

        RelativeLayout relativeLayout = findViewById(R.id.rl1);  //获取布局对象
        AnimationDrawable anumation = (AnimationDrawable) relativeLayout.getBackground();  //获取drawable动画资源

        relativeLayout.setOnClickListener(new View.OnClickListener() {   //布局点击事件
            @Override
            public void onClick(View view) {
                if (flag){
                    anumation.start();   //启动
                    flag = false;
                }else {
                    anumation.stop();    //停止
                    flag = true;
                }
            }
        });
    }
}

点击后启动,再点击停止,如此反复…
Android学习|动画——逐帧、补间、属性动画_第1张图片

Android学习|动画——逐帧、补间、属性动画_第2张图片


2、补间动画 (补帧)

补间动画(tweened animation): 设置初始值、结束值。中间动态由安卓完成。

例如:图片设置初始透明度为0%,结束为100%.画面播放则是由0——100渐变,由安卓补间动画完成

2.1 类型

1、 alpha 透明度
2、 rotate 旋转
3.、scale 缩放
4、 translate 平移

1、 alpha 透明度 Demo

设置透明度起始为0,结束为1,5秒完成变化

android:duration=“5000”
android:fromAlpha=“1”
android:toAlpha=“0”


<set xmlns:android="http://schemas.android.com/apk/res/android">


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

set>
2.、rotate 旋转 Demo

起始为0位置不变,最终为360,则旋转360度, pivotx、pivotY设置旋转锚点

android:duration=“5000”
android:fromDegrees=“0”
android:pivotX=“50%”
android:pivotY=“50%”
android:toDegrees=“360”


<set xmlns:android="http://schemas.android.com/apk/res/android">



    <rotate
        android:duration="5000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360">rotate>

set>
3、scale 缩放 Demo

起始xy轴都是1,不缩放,最后为0.5,则缩放0.5。 pivotx、pivotY设置锚点

android:duration=“5000”
android:fromXScale=“1”
android:fromYScale=“1”
android:pivotX=“50%”
android:pivotY=“50%”
android:toXScale=“0.5”
android:toYScale=“0.5”


<set xmlns:android="http://schemas.android.com/apk/res/android">



    <scale
        android:duration="5000"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0.5"
        android:toYScale="0.5">scale>

set>
4、 translate 平移 Demo

初始xy都是0,位置不变,最后xy都移动400dp,2秒完成

android:duration=“4000”
android:fromXDelta=“0”
android:fromYDelta=“0”
android:toXDelta=“300”
android:toYDelta=“300”


<set xmlns:android="http://schemas.android.com/apk/res/android">


    <translate
        android:duration="4000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="300"
        android:toYDelta="300">translate>


set>

2.2 Java代码中设置动画绑定

        对要进行改变的组件,设置点击事件。然后点击事件中通过 加载xml动画设置文件来创建一个Animation对象

通过加载xml动画设置文件来创建一个Animation对象
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);

然后通过startAnimation(),启动设置的动画(参数为创建的Animation动画对象)

imgView.startAnimation(animation); //启动设置的动画


完整Java代码如下,可根据不同类型,改变注释(透明度、旋转…)

package com.example.thriddemo_animation_2;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
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 {

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

        ImageView imgView = findViewById(R.id.iv);

        imgView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //通过加载xml动画设置文件来创建一个Animation对象

                //1、透明度demo
                //Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);

                //2、旋转demo
                //Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate);

                //3、缩放demo
                //Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale);

                //4、平移demo
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate);


                imgView.startAnimation(animation);  //启动设置的动画
            }
        });


    }
}

2.3、ctivity_main.xml中的代码


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

    <ImageView
        android:id="@+id/iv"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:adjustViewBounds="true"
        android:src="@drawable/img2"
        >ImageView>

LinearLayout>



3.属性动画

属性动画,即对组件的属性进行改变,从而达到动画的效果。(例如,透明度属性从0-1.0渐变)


主要通过 ValueAnimatorObjectAnimator,然后可选择性地配合监听器完成。

1、ValueAnimator

ValueAnimator anim = valueAnimator.ofFLoat(of,1f);

anim.setDuration(2000); //设置动画完成事件

anim.addUpdateListener(new valueAnimator.AnimatorupdateListener() {
       @override
        public void onAnimationupdate(valueAnimator animation){
                    xxxxxxxx…
                    Log.e(“leo”,"onAnimationUpdate: "+ valueAnimator.getAnimatedValue());
        }
});

anim.start(); //启动ValueAnimator


2、ObjectAnimator

ObjectAnimator继承自ValueAnimator,它可直接针对对象,可对对象的属性进行改变(通过get,set方法)

ObjectAnimator.ofFLoat(textview,propertyName: “alpha”, …values:of,1f);

先通过上面的方法设置组件的效果,如上即为:设置textview组件的属性alpha,从0变为1。该方法返回ObjectAnimator对象。

然后可objectAnimator.setDuration(4000)设置动画完成时长。

最后objectAnimator.start();启动动画


代码如下
package com.example.thirddemo_animation_3;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

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

        //ObjectAnimator
        TextView textView = findViewById(R.id.tv);
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
        objectAnimator.setDuration(4000);
        objectAnimator.start();

    }
}

效果是启动时,"Hello World!"先不可见,然后逐渐透明度增高,变为可见。
Android学习|动画——逐帧、补间、属性动画_第3张图片


监听器

      动画在诞生到生效,最后到结束过程中,有时候不同阶段需要做不同事情,可对其进行监听。其主要通过 objectAnimator.addListener() 方法实现。
      而在该方法中,可new Animator.AnimatorListener() 创建实现类,其实现的是AnimatorListener接口,重写会包含如下方法

onAnimationStart()          动画开始的时候调用
onAnimationEnd()            动画结束的时候调用
onAnimationCancel()       动画被取消的时候调用
onAnimationRepeat()       动画重复执行的时候调用

       使用AnimatorListener需要全部方法重写,但是对于个别方法的使用,可采用抽象类AnimatorListenerAdapter,该类实现了AnimatorListener接口。


AnimatorListener

//监听器
        objectAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {   //动画开始时使用

            }

            @Override
            public void onAnimationEnd(Animator animator) {     //动画开始时使用

            }

            @Override
            public void onAnimationCancel(Animator animator) {     //动画被取消时使用

            }

            @Override
            public void onAnimationRepeat(Animator animator) {     //动画重复执行时使用

            }
        });

AnimatorListenerAdapter

 //适配的方式,即不实现接口,而是实现其抽象类,然后可选择行的进行方法的重写
        objectAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                Log.e("leo","onAnimationStart");
            }
        });




整个属性动画的java代码如下:

package com.example.thirddemo_animation_3;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

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

        //ValueAnimator
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
        valueAnimator.setDuration(2000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                Log.e("leo","onAnimationUpdate: "+ valueAnimator.getAnimatedValue());
            }
        });
        valueAnimator.start();


        //ObjectAnimator
        TextView textView = findViewById(R.id.tv);
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
        objectAnimator.setDuration(4000);
        objectAnimator.start();


        //监听器
        objectAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {   //动画开始时使用

            }

            @Override
            public void onAnimationEnd(Animator animator) {     //动画开始时使用

            }

            @Override
            public void onAnimationCancel(Animator animator) {     //动画被取消时使用

            }

            @Override
            public void onAnimationRepeat(Animator animator) {     //动画重复执行时使用

            }
        });

        //适配的方式,即不实现接口,而是实现其抽象类,然后可选择行的进行方法的重写
        objectAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                Log.e("leo","onAnimationStart");
            }
        });






    }
}

你可能感兴趣的:(Android,动画,android,学习)