Android开发:帧动画,补间动画和属性动画的使用

本文参考:二哥cjpnice原博客

帧动画

  • 效果图
    帧动画

在drawable中新建资源文件frame_anim.xml,使用animation-list定义动画,animation-list定义的动画将顺次从上往下显示item内的图片,设置oneshot=false则反复循环执行,true则执行一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<animation-list android:oneshot="false" xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/anim_1"
android:duration="100"/>
<item
android:drawable="@drawable/anim_2"
android:duration="100"/>
<item
android:drawable="@drawable/anim_3"
android:duration="100"/>
<item
android:drawable="@drawable/anim_4"
android:duration="100"/>

</animation-list>

在layout布局文件activity_frame_anim中使用ImageView,将上一步写好的动画通过src或background引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FrameAnimActivity">

<ImageView
android:id="@+id/frame_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/frame_anim"/>

</LinearLayout>

在FrameAnimActivity中启动动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.huatec.edu.demoactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.widget.ImageView;

public class FrameAnimActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame_anim);
ImageView imageView = findViewById(R.id.frame_image);
imageView.setImageResource(R.drawable.frame_anim);
AnimationDrawable animationDrawable = (AnimationDrawable)imageView.getDrawable();
animationDrawable.start();
}
}

补间动画(视图动画)

淡入淡出动画(Alpha),缩放动画(Scale),位移动画(Translate),旋转动画(Roate)

  • 效果图
    补间动画

在res目录下新建anim资源目录,并在anim中分别新建动画资源文件

  • alpha_anim.xml

    1
    2
    3
    4
    5
    6
    7
    8
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
    android:duration="2000"
    android:fromAlpha="1.0"
    android:toAlpha="0.0" />

    </set>
  • scale_anim.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
    android:fromXScale="0.0"
    android:toXScale="1.5"
    android:fromYScale="0.2"
    android:toYScale="1.5"
    android:pivotX="50"
    android:pivotY="50"
    android:duration="2000" />

    </set>
  • translate_anim.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="3000"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:repeatCount="infinite"
    android:toXDelta="200"
    android:toYDelta="200"/>

    </set>
  • roate_anim.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
    android:fromDegrees="0"
    android:toDegrees="-650"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="3000"
    android:fillAfter="true">
    </rotate>

    </set>

在layout布局文件activity_main.xml中放入一个ImageView,和4个Button按钮用来显示和切换动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ImageView
android:id="@+id/test"
android:layout_width="240dp"
android:layout_height="240dp"
android:layout_marginTop="152dp"
android:src="@drawable/test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.514"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Alpha"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Scale"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/button1"
tools:ignore="MissingConstraints" />

<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Translate"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/button2"
tools:ignore="MissingConstraints" />

<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginBottom="16dp"
android:text="Roate"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/button3"
tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

在MainActivity中实现切换,加载并开启动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.huatec.edu.hw7avtivity;

import androidx.appcompat.app.AppCompatActivity;

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 {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button alpha = findViewById(R.id.button1);
Button scale = findViewById(R.id.button2);
Button translate = findViewById(R.id.button3);
Button roate = findViewById(R.id.button4);
alpha.setOnClickListener(this);
scale.setOnClickListener(this);
translate.setOnClickListener(this);
roate.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:setAnimation(R.anim.alpha_anim);
break;
case R.id.button2:setAnimation(R.anim.scale_anim);
break;
case R.id.button3:setAnimation(R.anim.translate_anim);
break;
case R.id.button4:setAnimation(R.anim.roate_anim);
break;

}
}

private void setAnimation(int ResourceId) {
Animation animation = AnimationUtils.loadAnimation(this,ResourceId);
ImageView imageView = findViewById(R.id.test);
imageView.startAnimation(animation);
}

}

属性动画

实现边先小后大边摇晃的动画效果

  • 效果图
    属性动画

在layout布局文件activity_shake_anim.xml中放入一个ImageView用来显示动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ShakeAnimActivity">
<ImageView
android:id="@+id/shake"
android:layout_width="240dp"
android:layout_height="240dp"
android:layout_marginTop="152dp"
android:src="@drawable/test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.514"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

在ShakeAnimActivity中实现切换,加载并开启动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.huatec.edu.hw7avtivity;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

import androidx.appcompat.app.AppCompatActivity;

public class ShakeAnimActivity extends AppCompatActivity {

ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shake_anim);
imageView=findViewById(R.id.shake);
initAnimation();
}
//缩放
private void initAnimation(){
final AnimatorSet scaleAnimSet = new AnimatorSet();
imageView.setPivotX(imageView.getWidth()+250);
imageView.setPivotY(imageView.getWidth()+250);
scaleAnimSet.playTogether(
ObjectAnimator.ofFloat(imageView,"scaleX",0,1).setDuration(2000),
ObjectAnimator.ofFloat(imageView,"scaleY",0,1).setDuration(2000));
scaleAnimSet.start();
imageView.setAnimation(shakeAnim(6));
}
public static Animation shakeAnim(int counts) {
Animation rotateAnimation = new RotateAnimation(0, 20, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new CycleInterpolator(counts));
rotateAnimation.setRepeatCount(-1);
rotateAnimation.setDuration(3000);
return rotateAnimation;
}
}

推荐一个学习Android的好地方

菜鸟教程