Android动画学习之帧动画

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();
    }
}
相关推荐
咖啡の猫1 小时前
Android开发-常用布局
android·gitee
程序员老刘2 小时前
Google突然“变脸“,2026年要给全球开发者上“紧箍咒“?
android·flutter·客户端
Tans52 小时前
Androidx Lifecycle 源码阅读笔记
android·android jetpack·源码阅读
雨白2 小时前
实现双向滑动的 ScalableImageView(下)
android
峥嵘life2 小时前
Android Studio新版本编译release版本apk实现
android·ide·android studio
studyForMokey5 小时前
【Android 消息机制】Handler
android
敲代码的鱼哇5 小时前
跳转原生系统设置插件 支持安卓/iOS/鸿蒙UTS组件
android·ios·harmonyos
翻滚丷大头鱼5 小时前
android View详解—动画
android
我是好小孩5 小时前
[Android]RecycleView的item用法
android
胖虎15 小时前
Android Studio 读取本地文件(以 ZIP 为例)
android·ide·android studio·本地文件·读取本地文件