Android App开发中补间动画的讲解以及实现钟摆动画效果实战(附源码 简单易懂 可直接使用)

简介: Android App开发中补间动画的讲解以及实现钟摆动画效果实战(附源码 简单易懂 可直接使用)

需要图片集和源码请点赞关注收藏后评论区留言~~~

一、补间动画的种类

Android提供了补间动画,它允许开发者实现某个视图的动态变换,具体包括四种动画效果,分别是灰度动画,平移动画,缩放动画和旋转动画。因为开发者提供动画的起始状态值与终止状态值,然后系统按照时间推移计算中间的状态值,并自动把中间状态的视图补充到起止视图的变化过程中,自动补充中间视图的动画就被简称为补间动画

四种补间动画有不同的初始化方式 具体说明如下

1:灰度动画 在构造方法中指定视图透明度的前后数值

2:平移动画 指定平移前后左上角的坐标值

3:缩放动画 指定视图的前后缩放比例

4:旋转动画 指定视图的旋转角度

可在下拉框中选择不同的动画效果 演示视频已上传至我的主页 有需要可自行观看

代码如下

Java类

package com.example.animation;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
import com.example.animation.util.Utils;
public class TweenAnimActivity extends AppCompatActivity implements AnimationListener {
    private ImageView iv_tween_anim; // 声明一个图像视图对象
    private Animation alphaAnim, translateAnim, scaleAnim, rotateAnim; // 声明四个补间动画对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tween_anim);
        iv_tween_anim = findViewById(R.id.iv_tween_anim);
        initTweenAnim(); // 初始化补间动画
        initTweenSpinner(); // 初始化动画类型下拉框
    }
    // 初始化补间动画
    private void initTweenAnim() {
        // 创建一个灰度动画。从完全透明变为即将不透明
        alphaAnim = new AlphaAnimation(1.0f, 0.1f);
        alphaAnim.setDuration(3000); // 设置动画的播放时长
        alphaAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个平移动画。向左平移100dp
        translateAnim = new TranslateAnimation(1.0f, Utils.dip2px(this, -100), 1.0f, 1.0f);
        translateAnim.setDuration(3000); // 设置动画的播放时长
        translateAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个缩放动画。宽度不变,高度变为原来的二分之一
        scaleAnim = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.5f);
        scaleAnim.setDuration(3000); // 设置动画的播放时长
        scaleAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个旋转动画。围绕着圆心顺时针旋转360度
        rotateAnim = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnim.setDuration(3000); // 设置动画的播放时长
        rotateAnim.setFillAfter(true); // 设置维持结束画面
    }
    // 初始化动画类型下拉框
    private void initTweenSpinner() {
        ArrayAdapter<String> tweenAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, tweenArray);
        Spinner sp_tween = findViewById(R.id.sp_tween);
        sp_tween.setPrompt("请选择补间动画类型");
        sp_tween.setAdapter(tweenAdapter);
        sp_tween.setOnItemSelectedListener(new TweenSelectedListener());
        sp_tween.setSelection(0);
    }
    private String[] tweenArray = {"灰度动画", "平移动画", "缩放动画", "旋转动画"};
    class TweenSelectedListener implements OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            playTweenAnim(arg2); // 播放指定类型的补间动画
        }
        public void onNothingSelected(AdapterView<?> arg0) {}
    }
    // 播放指定类型的补间动画
    private void playTweenAnim(int type) {
        if (type == 0) { // 灰度动画
            iv_tween_anim.startAnimation(alphaAnim); // 开始播放灰度动画
            // 给灰度动画设置动画事件监听器
            alphaAnim.setAnimationListener(TweenAnimActivity.this);
        } else if (type == 1) { // 平移动画
            iv_tween_anim.startAnimation(translateAnim); // 开始播放平移动画
            // 给平移动画设置动画事件监听器
            translateAnim.setAnimationListener(TweenAnimActivity.this);
        } else if (type == 2) { // 缩放动画
            iv_tween_anim.startAnimation(scaleAnim); // 开始播放缩放动画
            // 给缩放动画设置动画事件监听器
            scaleAnim.setAnimationListener(TweenAnimActivity.this);
        } else if (type == 3) { // 旋转动画
            iv_tween_anim.startAnimation(rotateAnim); // 开始播放旋转动画
            // 给旋转动画设置动画事件监听器
            rotateAnim.setAnimationListener(TweenAnimActivity.this);
        }
    }
    // 在补间动画开始播放时触发
    @Override
    public void onAnimationStart(Animation animation) {}
    // 在补间动画结束播放时触发
    @Override
    public void onAnimationEnd(Animation animation) {
        if (animation.equals(alphaAnim)) { // 灰度动画
            // 创建一个灰度动画。从即将不透明变为完全透明
            Animation alphaAnim2 = new AlphaAnimation(0.1f, 1.0f);
            alphaAnim2.setDuration(3000); // 设置动画的播放时长
            alphaAnim2.setFillAfter(true); // 设置维持结束画面
            iv_tween_anim.startAnimation(alphaAnim2); // 开始播放灰度动画
        } else if (animation.equals(translateAnim)) { // 平移动画
            // 创建一个平移动画。向右平移100dp
            Animation translateAnim2 = new TranslateAnimation(Utils.dip2px(this, -100), 1.0f, 1.0f, 1.0f);
            translateAnim2.setDuration(3000); // 设置动画的播放时长
            translateAnim2.setFillAfter(true); // 设置维持结束画面
            iv_tween_anim.startAnimation(translateAnim2); // 开始播放平移动画
        } else if (animation.equals(scaleAnim)) { // 缩放动画
            // 创建一个缩放动画。宽度不变,高度变为原来的两倍
            Animation scaleAnim2 = new ScaleAnimation(1.0f, 1.0f, 0.5f, 1.0f);
            scaleAnim2.setDuration(3000); // 设置动画的播放时长
            scaleAnim2.setFillAfter(true); // 设置维持结束画面
            iv_tween_anim.startAnimation(scaleAnim2); // 开始播放缩放动画
        } else if (animation.equals(rotateAnim)) { // 旋转动画
            // 创建一个旋转动画。围绕着圆心逆时针旋转360度
            Animation rotateAnim2 = new RotateAnimation(0f, -360f,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rotateAnim2.setDuration(3000); // 设置动画的播放时长
            rotateAnim2.setFillAfter(true); // 设置维持结束画面
            iv_tween_anim.startAnimation(rotateAnim2); // 开始播放旋转动画
        }
    }
    // 在补间动画重复播放时触发
    @Override
    public void onAnimationRepeat(Animation animation) {}
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right"
            android:text="补间动画类型:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <Spinner
            android:id="@+id/sp_tween"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:spinnerMode="dialog" />
    </LinearLayout>
    <ImageView
        android:id="@+id/iv_tween_anim"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:src="@drawable/oval" />
</LinearLayout>

二、补间动画的原理以及钟摆的实现

补间动画只提供了基本的动态变换,如果想要复杂的动画效果,比如像钟摆一样左摆一下右摆一下,就要对它进行改造 钟摆的操作主要由以下三段动作组成

1:以上面端点为圆心 转到左边某个角度停住

2:从左边向右边旋转 转到右边某个角度停住

3:从右再向左转 完成一个周期

效果如下 动画演示视频已上传至个人主页 有需要可自行前往观看

代码如下

Java类

package com.example.animation;
import com.example.animation.widget.SwingAnimation;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.animation.Animation;
import android.widget.ImageView;
public class SwingAnimActivity extends AppCompatActivity {
    private ImageView iv_swing; // 声明一个图像视图对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_swing_anim);
        iv_swing = findViewById(R.id.iv_swing);
        findViewById(R.id.ll_swing).setOnClickListener(v -> showSwingAnimation());
        showSwingAnimation(); // 开始播放摇摆动画
    }
    // 开始播放摇摆动画
    private void showSwingAnimation() {
        // 创建一个摇摆动画
        // 参数取值说明:中间度数、摆到左侧的度数、摆到右侧的度数、圆心X坐标类型、圆心X坐标相对比例、圆心Y坐标类型、圆心Y坐标相对比例
        // 坐标类型有三种:ABSOLUTE 绝对坐标,RELATIVE_TO_SELF 相对自身的坐标,RELATIVE_TO_PARENT 相对上级视图的坐标
        // X坐标相对比例,为0时表示左边顶点,为1表示右边顶点,为0.5表示水平中心点
        // Y坐标相对比例,为0时表示上边顶点,为1表示下边顶点,为0.5表示垂直中心点
        SwingAnimation swingAnimation = new SwingAnimation(
                0f, 60f, -60f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.0f);
        swingAnimation.setDuration(4000); // 设置动画的播放时长
        swingAnimation.setRepeatCount(0); // 设置动画的重播次数
        swingAnimation.setFillAfter(false); // 设置维持结束画面
        swingAnimation.setStartOffset(500); // 设置动画的启动延迟
        iv_swing.startAnimation(swingAnimation); // 开始播放摇摆动画
    }
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_swing"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/clock_top" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/clock_bg" />
        <ImageView
            android:id="@+id/iv_swing"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/clock_bottom" />
    </RelativeLayout>
</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
4天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
5天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
7天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
5天前
|
存储 API 开发工具
探索安卓开发:从基础到进阶
【10月更文挑战第37天】在这篇文章中,我们将一起探索安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和建议。我们将从安卓开发的基础开始,逐步深入到更复杂的主题,如自定义组件、性能优化等。最后,我们将通过一个代码示例来展示如何实现一个简单的安卓应用。让我们一起开始吧!
|
6天前
|
存储 XML JSON
探索安卓开发:从新手到专家的旅程
【10月更文挑战第36天】在这篇文章中,我们将一起踏上一段激动人心的旅程,从零基础开始,逐步深入安卓开发的奥秘。无论你是编程新手,还是希望扩展技能的老手,这里都有适合你的知识宝藏等待发掘。通过实际的代码示例和深入浅出的解释,我们将解锁安卓开发的关键技能,让你能够构建自己的应用程序,甚至贡献于开源社区。准备好了吗?让我们开始吧!
18 2
|
7天前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
15天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
14天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
28 5
|
12天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
14天前
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
33 3

热门文章

最新文章