Android App开发中集合动画和属性动画的讲解及实战演示(附源码 简单易懂 可直接使用)

news2024/11/17 23:34:59

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

一、集合动画

有时一个动画效果会加入多种动画,比如一个旋转一边缩放,这时便会用到集合动画AnimationSet把几个补间动画组装起来,实现让某视图同时呈现多种动画的效果

因为集合动画和补间动画一样继承自Animation类,所以拥有补间动画的基本方法,集合动画不像一般补间动画那样提供构造方法,而是通过addAnimation方法把别的补间动画加入本集合动画中

效果如下 它可以把补间动画中多种情况得以演示效果合成一个动画,因此也成为集合动画

集合动画

 代码如下

Java类

package com.example.animation;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

public class AnimSetActivity extends AppCompatActivity implements AnimationListener {
    private ImageView iv_anim_set; // 声明一个图像视图对象
    private AnimationSet setAnim; // 声明一个集合动画对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_anim_set);
        iv_anim_set = findViewById(R.id.iv_anim_set);
        iv_anim_set.setOnClickListener(v -> startAnim());
        initAnimation(); // 初始化集合动画
    }

    // 初始化集合动画
    private void initAnimation() {
        // 创建一个灰度动画
        Animation alphaAnim = new AlphaAnimation(1.0f, 0.1f);
        alphaAnim.setDuration(3000); // 设置动画的播放时长
        alphaAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个平移动画
        Animation translateAnim = new TranslateAnimation(1.0f, -200f, 1.0f, 1.0f);
        translateAnim.setDuration(3000); // 设置动画的播放时长
        translateAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个缩放动画
        Animation scaleAnim = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.5f);
        scaleAnim.setDuration(3000); // 设置动画的播放时长
        scaleAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个旋转动画
        Animation rotateAnim = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnim.setDuration(3000); // 设置动画的播放时长
        rotateAnim.setFillAfter(true); // 设置维持结束画面
        // 创建一个集合动画
        setAnim = new AnimationSet(true);
        // 下面在代码中添加集合动画
        setAnim.addAnimation(alphaAnim); // 给集合动画添加灰度动画
        setAnim.addAnimation(translateAnim); // 给集合动画添加平移动画
        setAnim.addAnimation(scaleAnim); // 给集合动画添加缩放动画
        setAnim.addAnimation(rotateAnim); // 给集合动画添加旋转动画
        setAnim.setFillAfter(true); // 设置维持结束画面
        startAnim(); // 开始播放集合动画
    }

    // 开始播放集合动画
    private void startAnim() {
        iv_anim_set.startAnimation(setAnim); // 开始播放动画
        setAnim.setAnimationListener(this); // 设置动画事件监听器
    }

    // 在补间动画开始播放时触发
    @Override
    public void onAnimationStart(Animation animation) {}

    // 在补间动画结束播放时触发
    @Override
    public void onAnimationEnd(Animation animation) {
        if (animation.equals(setAnim)) { // 原集合动画播放完毕,接着播放倒过来的集合动画
            // 创建一个灰度动画
            Animation alphaAnim2 = new AlphaAnimation(0.1f, 1.0f);
            alphaAnim2.setDuration(3000); // 设置动画的播放时长
            alphaAnim2.setFillAfter(true); // 设置维持结束画面
            // 创建一个平移动画
            Animation translateAnim2 = new TranslateAnimation(-200f, 1.0f, 1.0f, 1.0f);
            translateAnim2.setDuration(3000); // 设置动画的播放时长
            translateAnim2.setFillAfter(true); // 设置维持结束画面
            // 创建一个缩放动画
            Animation scaleAnim2 = new ScaleAnimation(1.0f, 1.0f, 0.5f, 1.0f);
            scaleAnim2.setDuration(3000); // 设置动画的播放时长
            scaleAnim2.setFillAfter(true); // 设置维持结束画面
            // 创建一个旋转动画
            Animation rotateAnim2 = new RotateAnimation(0f, -360f,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rotateAnim2.setDuration(3000); // 设置动画的播放时长
            rotateAnim2.setFillAfter(true); // 设置维持结束画面
            // 创建一个集合动画
            AnimationSet setAnim2 = new AnimationSet(true);
            setAnim2.addAnimation(alphaAnim2); // 给集合动画添加灰度动画
            setAnim2.addAnimation(translateAnim2); // 给集合动画添加平移动画
            setAnim2.addAnimation(scaleAnim2); // 给集合动画添加缩放动画
            setAnim2.addAnimation(rotateAnim2); // 给集合动画添加旋转动画
            setAnim2.setFillAfter(true); // 设置维持结束画面
            iv_anim_set.startAnimation(setAnim2); // 开始播放动画
        }
    }

    // 在补间动画重复播放时触发
    @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">

    <ImageView
        android:id="@+id/iv_anim_set"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:src="@drawable/oval" />

</LinearLayout>

二、属性动画

属性动画突破了补间动画的局限,允许视图的所有属性都能实现渐变的动画效果,例如背景颜色,文字颜色,文字大小等等。只要设定某属性的起始值与终止值,渐变的持续时间,属性动画就可以实现渐变效果。 下面是ObjectAnimator的常用方法

ofInt 定义整形属性的属性动画

ofFloat 定义浮点型属性的属性动画

ofArgb 定义颜色属性的属性动画

ofObject 定义对象属性的属性动画

以上四个of方法的第一个参数为宿主视图对象,第二个参数为需要变化的属性名称,从第三个参数开始以及后面的参数为属性变化的各个状态值。

下面是用属性动画分别实现透明度,平移,缩放,旋转等变换操作的效果

可以在下拉框选项中选择自己想要的动画类型

裁剪动画

 

 

 代码如下

Java类

package com.example.animation;

import android.animation.RectEvaluator;
import android.animation.ObjectAnimator;
import android.graphics.Rect;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;

public class ObjectAnimActivity extends AppCompatActivity {
    private ImageView iv_object_anim; // 声明一个图像视图对象
    private ObjectAnimator alphaAnim, translateAnim, scaleAnim, rotateAnim; // 声明四个属性动画对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_object_anim);
        iv_object_anim = findViewById(R.id.iv_object_anim);
        initObjectAnim(); // 初始化属性动画
        initObjectSpinner(); // 初始化动画类型下拉框
    }

    // 初始化属性动画
    private void initObjectAnim() {
        // 构造一个在透明度上变化的属性动画
        alphaAnim = ObjectAnimator.ofFloat(iv_object_anim, "alpha", 1f, 0.1f, 1f);
        // 构造一个在横轴上平移的属性动画
        translateAnim = ObjectAnimator.ofFloat(iv_object_anim, "translationX", 0f, -200f, 0f, 200f, 0f);
        // 构造一个在纵轴上缩放的属性动画
        scaleAnim = ObjectAnimator.ofFloat(iv_object_anim, "scaleY", 1f, 0.5f, 1f);
        // 构造一个围绕中心点旋转的属性动画
        rotateAnim = ObjectAnimator.ofFloat(iv_object_anim, "rotation", 0f, 360f, 0f);
    }

    // 初始化动画类型下拉框
    private void initObjectSpinner() {
        ArrayAdapter<String> objectAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, objectArray);
        Spinner sp_object = findViewById(R.id.sp_object);
        sp_object.setPrompt("请选择属性动画类型");
        sp_object.setAdapter(objectAdapter);
        sp_object.setOnItemSelectedListener(new ObjectSelectedListener());
        sp_object.setSelection(0);
    }

    private String[] objectArray = {"灰度动画", "平移动画", "缩放动画", "旋转动画", "裁剪动画"};
    class ObjectSelectedListener implements OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            playObjectAnim(arg2); // 播放指定类型的属性动画
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

    // 播放指定类型的属性动画
    private void playObjectAnim(int type) {
        ObjectAnimator anim = null;
        if (type == 0) { // 灰度动画
            anim = alphaAnim;
        } else if (type == 1) { // 平移动画
            anim = translateAnim;
        } else if (type == 2) { // 缩放动画
            anim = scaleAnim;
        } else if (type == 3) { // 旋转动画
            anim = rotateAnim;
        } else if (type == 4) { // 裁剪动画
            int width = iv_object_anim.getWidth();
            int height = iv_object_anim.getHeight();
            // 构造一个从四周向中间裁剪的属性动画
            ObjectAnimator clipAnim = ObjectAnimator.ofObject(iv_object_anim, "clipBounds",
                    new RectEvaluator(), new Rect(0, 0, width, height),
                    new Rect(width / 3, height / 3, width / 3 * 2, height / 3 * 2),
                    new Rect(0, 0, width, height));
            anim = clipAnim;
        }
        if (anim != null) {
            anim.setDuration(3000); // 设置动画的播放时长
            anim.start(); // 开始播放属性动画
        }
    }

}

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_object"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:spinnerMode="dialog" />

    </LinearLayout>

    <ImageView
        android:id="@+id/iv_object_anim"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:src="@drawable/oval" />

</LinearLayout>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/22465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jetson Orin使用Yolo5开源数据集训练模型检测口罩

软硬件环境&#xff1a; 乌班图 20.04 64位蟒蛇与 3.8.10英伟AGX Orin库达11.4PyTorch1.12YOLOv5-6.1感谢开源数据集下载地址 正常都是自己收集完了训练&#xff0c;今天就省略这个步骤了。 如果想自己制作看下面的流程。 软硬件环境搭建教程链接 刷机的话使用官方教程或者…

DNS协议

DNS服务器 人类更喜欢记忆主机名&#xff0c;而路由器更喜欢定长的、有结构层次的IP地址&#xff0c;DNS应运而生&#xff1a;DNS能进行主机名到IP地址转换的目录服务。 DSN是&#xff1a; &#xff08;1&#xff09;一个由分层的DNS服务器&#xff08;DNS server&#xff09;实…

元数据管理-解决方案调研二:元数据管理解决方案——Saas/内部解决方案(2)

Saas/内部解决方案 2.5、Azure Purview 地址&#xff1a;Azure Purview - Unified Data Governance Solution | Microsoft Azure 特点&#xff1a; 1、创建跨整个数据资产的统一数据地图&#xff0c;为有效的数据治理和使用奠定基础 1.1、自动化和管理混合源的元数据&#xf…

重打包实现frida持久化 笔记

修改Dex Using Frida on Android without root 修改so [翻译]在未root的设备上使用frida 2个方法本质都是通过重打包让app自己加载frida-gadget.so &#xff08;但感觉没有谁家app会让人轻易重打包吧。。。&#xff09; apktool d org.telegram.messenger_4.8.4-12207.apk -r…

Tomcat配置SSL证书别名tomcat无法识别密钥项

Tomcat配置SSL证书一直启动失败&#xff0c;主要问题如下&#xff1a; java.io.IOException: Alias name tomcat does not identify a key entry at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:280) 别名tomcat无法识别密钥项&#xff0c;是因…

STM32单片机远程控制大棚种植系统

想要更多项目私wo!!! 一、电路设计 ​​​​​系统示意图硬件系统 系统由五个单片机系统组成的&#xff0c;其中51系列的单片机四个&#xff0c;STM32F407单片机一个&#xff0c;各个子系统之间通过NRF24L01无线模块进行通信。 系统硬件组成框图​​​​主控制板主要由STM32…

【VuePress2.0】快速开始(不用)

文章目录VuePress2.x1.1 安装安装VuePress2.x&#xff08;手动安装&#xff09;1.2 VuePress2.x 基本操作VuePress2.x主题2.1 安装VuePress2.x主题&#xff08;yarn&#xff09;2.2 报错解决&#xff08;没效果&#xff0c;不用看&#xff09;2.3 VuePress2.x主题 基本操作VueP…

Java基础深化和提高-------IO流

目录 IO流技术介绍 什么是IO 什么是数据源 流的概念 第一个简单的IO流程序 IO流的经典写法 IO流新语法经典写法 Java中流的概念细分 按流的方向分类&#xff1a; 按处理的数据单元分类&#xff1a; 按处理对象不同分类&#xff1a; Java中IO流类的体系 Java中IO的四大抽象…

CleanMyMac X真正好用的Mac电脑系统优化软件应用工具

最用户友好的Mac问题修复程序。删除系统垃圾、不需要的应用程序和恶意软件&#xff0c;并调整您的Mac以获得最高速度。对于速度较慢的计算机&#xff0c;CleanMyMac就能立即使用。 CleanMyMac2023之所以能够获得众多Mac的老用户们的喜爱&#xff0c;是因为其有着非常强大功能提…

数据可视化之大数据平台可视化

一 前言 在简化数据量和降低大数据应用的复杂性中&#xff0c;大数据分析发挥着关键的作用。可视化是其中一个重要的途径&#xff0c;它能够帮助大数据获得完整的数据视图并挖掘数据的价值。大数据分析和可视化应该无缝连接&#xff0c;这样才能在大数据应用中发挥最大的功效。…

nodejs+mysql航空飞机票销售酒店预订系统vue

(1)对机票预订管理系统进行需求分析、确定所需要的模块&#xff1b;建立数据字典、数据流等&#xff1b;书写可行性分析和需求分析说明书。 (2)对机票预订管理系统进行概要设计&#xff1a;建立软件体系结构&#xff0c;画出用例图、E-R图等&#xff1b;书写数据要求说明书和各…

【雷达通信】阵列信号处理(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

聊聊Go里面的闭包

以前写 Java 的时候&#xff0c;听到前端同学谈论闭包&#xff0c;觉得甚是新奇&#xff0c;后面自己写了一小段时间 JS&#xff0c;虽只学到皮毛&#xff0c;也大概了解到闭包的概念&#xff0c;现在工作常用语言是 Go&#xff0c;很多优雅的代码中总是有闭包的身影&#xff0…

嵌入式图形开发框架Qt——让牙科手术开始迈入机器人时代

Neocis软件工程总监,Jim Tieman&#xff1a; “我们Neocis是一家致力于提高科医生能力和促进病人护理的牙科机器人公司。之前我们有一个Microsoft Foundations Class (MFC)的应用程序&#xff0c;由于现在团队擅长MFC开发的技术员并不多&#xff0c;维护起来也很费劲。之前这个…

AST 初探深浅,代码还能这样玩?

AST 听起来好像是个很新的东西&#xff0c;那么具体有什么用&#xff0c;好不好用就在这篇文章中找到答案吧~ 我们简单将这个词拆分抽象、语法、树&#xff0c;如果我们能够顺利将这个词拆分&#xff0c;那么我们也就掌握了其核心所在 抽象&#xff1a;抽象的反义词是具象&…

微信小程序|使用小程序制作一个2048小游戏

文章目录一、文章前言二、创建小程序三、功能开发一、文章前言 此文主要通过小程序实现2048游戏&#xff0c;游戏操作简单&#xff0c;容易上手。 规则&#xff1a;正常打开游戏的界面&#xff0c;会只有两个2&#xff0c;每次移动后都会出现一个2&#xff0c;数字大了之后会出…

RabbitMQ初步到精通-第八章-Java-AMQP-Client源码分析

目录 第八章-Java-AMQP-Client源码分析 1、背景 1.1 客户端介绍 1.2 看源码好处 1.3 如何看源码 2、生产者 3、消费者监听 4、创建连接 5、消费者消费 6. 总结&#xff1a; 第八章-Java-AMQP-Client源码分析 1、背景 1.1 客户端介绍 通过前面几章的学习&#xff0c;大家对…

工作以来一直在CRUD,Spring源码该怎么阅读?这份价值百万的源码解析让你如有神助!

初学SpringBoot框架时&#xff0c;第一次启动服务&#xff0c;直呼什么鬼&#xff1f;只需要简单的几步配置&#xff0c;几个核心的注解&#xff0c;就可以快速实现工程的搭建和运行&#xff1b; 虽然从Spring框架迁移到SpringBoot框架&#xff0c;在初期会有很多的不适应&…

谈谈对跨域(跨源)的一些理解

一、相关概念 1、什么是跨域&#xff1f; 跨域又称为跨源&#xff0c;是指在违反了浏览器的同源政策&#xff0c;也就是协议、域名和端口号三者不完全一致的情况下产生的。只要客户端与浏览器的三者有一项不同&#xff0c;就属于不同源&#xff0c;就会产生跨域。 很多初级开…

G 蛋白偶联受体与小分子化合物的相互作用

化学遗传学 (Chemogenetics) 是指一种蛋白被改造与先前未被识别的小分子化合物相互作用的过程。多种蛋白的改造已被报道&#xff0c;包括激酶、非激酶的酶类、G 蛋白偶联受体 (GPCRs) 和配体门控离子通道。化学遗传学技术 DREADDs (Designer receptors exclusively activated b…