Android动画学习之帧动画
android动画分为三大类,帧动画、属性动画(也称值动画)以及view(补间)动画,下面针对每一项进行说明。
帧动画
帧动画非常容易理解,其实就是简单的由N张静态图片收集起来,然后我们通过控制依次显示 这些图片,因为人眼"视觉残留"的原因,会让我们造成动画的"错觉",跟放电影的原理一样!
在android中实现帧动画,一般需要用的组件是[AnimationDrawable](AnimationDrawable | Android Developers (google.cn)),具体内容可以点击链接进入android开发者官网进行查看,官方给出的使用例子如下:
java// Load the ImageView that will host the animation and // set its background to our AnimationDrawable XML resource. ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image); img.setBackgroundResource(R.drawable.spin_animation); // Get the background, which has been compiled to an AnimationDrawable object. AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground(); // Start the animation (looped playback by default). frameAnimation.start();
然后下面开始我们的代码尝试吧
开始之前先来看一下效果图:
代码部分可以分为两种形式,xml静态设置 和动态设置:
- xml形式:
先在res的drawable文件目录新建一个xml文件,标签头也就是root element使用animation_list:
在其中定义要显示的每一个drawable和其显示时长,还可以声明是否循环播放,只需将属性oneshot设置为false即可:
然后将这个文件引用到要显示的位置,即ImageView的src或者background属性:
最后,还要注意一点,设置完成之后动画并不会自动播放,还需要在代码中手动设置将动画start:
- 动态设置形式:
java
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
doAnimation();
}
private void doAnimation() {
AppCompatImageView imageView = findViewById(R.id.second_iv);
AnimationDrawable animationDrawable = new AnimationDrawable();
animationDrawable.addFrame(getDrawable(R.color.black),300);
animationDrawable.addFrame(getDrawable(R.color.light_blue_50),300);
animationDrawable.addFrame(getDrawable(R.color.teal_700),300);
animationDrawable.addFrame(getDrawable(R.color.purple_500),300);
animationDrawable.setOneShot(false);
animationDrawable.start();
imageView.setImageDrawable(animationDrawable);
}
}
动态代码方式更加灵活,还以自定义View实现每帧动画在不同的位置播放,主要是需要重写onDraw方法,实时传入不同的左上右下四个顶点值来达到效果:
代码如下:
java
package com.example.myapplication.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import java.lang.reflect.Field;
/**
* @author Taozi
*/
public class SelfDefinitionView extends AppCompatImageView {
private AnimationDrawable drawable;
private int i;
public SelfDefinitionView(@NonNull Context context) {
super(context);
}
public SelfDefinitionView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SelfDefinitionView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
return super.setFrame(l, t, r, b);
}
public void setDrawable(AnimationDrawable drawable) {
this.drawable = drawable;
}
public void setPosition(int left ,int top) {
setFrame(left,top,left+200,top+200);
}
@Override
protected void onDraw(Canvas canvas) {
if (i>= 10) {
i = 0;
}
i++;
setPosition(i*100,i*100);
super.onDraw(canvas);
}
}
java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.AppCompatImageView;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import com.example.myapplication.view.SelfDefinitionView;
/**
* @author Taozi
*/
public class SecondActivity extends AppCompatActivity {
private SelfDefinitionView view;
private AnimationDrawable drawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frameLayout = new FrameLayout(this);
setContentView(frameLayout);
view = new SelfDefinitionView(this);
view.setImageResource(R.drawable.anim_list_01);
drawable = (AnimationDrawable) view.getDrawable();
drawable.start();
new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
frameLayout.removeAllViews();
frameLayout.addView(view);
}
@Override
public void onFinish() {
}
}.start();
}
}