Android 之 动画合集之补间动画

news2024/11/15 21:45:36

本节引言:

本节带来的是Android三种动画中的第二种——补间动画(Tween),和前面学的帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!好了,开始本节学习~


1.补间动画的分类和Interpolator

Andoird所支持的补间动画效果有如下这五种,或者说四种吧,第五种是前面几种的组合而已~

  • AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续 时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应<alpha/>标签!
  • ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点, 还有动画的持续时间;对应<scale/>标签!
  • TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续 时间即可;对应<translate/>标签!
  • RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画 持续时间和旋转的轴心;对应<rotate/>标签
  • AnimationSet:组合渐变,就是前面多种渐变的组合,对应<set/>标签

在开始讲解各种动画的用法之前,我们先要来讲解一个东西:Interpolator

用来控制动画的变化速度,可以理解成动画渲染器,当然我们也可以自己实现Interpolator 接口,自行来控制动画的变化速度,而Android中已经为我们提供了五个可供选择的实现类:

  • LinearInterpolator:动画以均匀的速度改变
  • AccelerateInterpolator:在动画开始的地方改变速度较慢,然后开始加速
  • AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,中间时加速
  • CycleInterpolator:动画循环播放特定次数,变化速度按正弦曲线改变: Math.sin(2 * mCycles * Math.PI * input)
  • DecelerateInterpolator:在动画开始的地方改变速度较快,然后开始减速
  • AnticipateInterpolator:反向,先向相反方向改变一段再加速播放
  • AnticipateOvershootInterpolator:开始的时候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator: 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
  • OvershottInterpolator:回弹,最后超出目的值然后缓慢改变到目的值

而这个东东,我们一般是在写动画xml文件时会用到,属性是:android:interpolator, 而上面对应的值是:@android:anim/linear_interpolator,其实就是驼峰命名法变下划线而已 AccelerateDecelerateInterpolator对应:@android:anim/accelerate_decelerate_interpolator!


2.各种动画的详细讲解

这里的android:duration都是动画的持续时间,单位是毫秒~


1)AlphaAnimation(透明度渐变)

anim_alpha.xml

<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromAlpha="1.0"  
    android:toAlpha="0.1"  
    android:duration="2000"/>

属性解释:

fromAlpha :起始透明度
toAlpha:结束透明度
透明度的范围为:0-1,完全透明-完全不透明


2)ScaleAnimation(缩放渐变)

anim_scale.xml

<scale xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:fromXScale="0.2"  
    android:toXScale="1.5"  
    android:fromYScale="0.2"  
    android:toYScale="1.5"  
    android:pivotX="50%"  
    android:pivotY="50%"  
    android:duration="2000"/>

属性解释:

  • fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例
  • toXScale/toYScale:沿着X轴/Y轴缩放的结束比例
  • pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点

3)TranslateAnimation(位移渐变)

anim_translate.xml

<translate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromXDelta="0"  
    android:toXDelta="320"  
    android:fromYDelta="0"  
    android:toYDelta="0"  
    android:duration="2000"/>

属性解释:

  • fromXDelta/fromYDelta:动画起始位置的X/Y坐标
  • toXDelta/toYDelta:动画结束位置的X/Y坐标

4)RotateAnimation(旋转渐变)

anim_rotate.xml

<rotate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromDegrees="0"  
    android:toDegrees="360"  
    android:duration="1000"  
    android:repeatCount="1"  
    android:repeatMode="reverse"/> 

属性解释:

  • fromDegrees/toDegrees:旋转的起始/结束角度
  • repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
  • repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!

5)AnimationSet(组合渐变)

非常简单,就是前面几个动画组合到一起而已~

anim_set.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/decelerate_interpolator"  
    android:shareInterpolator="true" >  
  
    <scale  
        android:duration="2000"  
        android:fromXScale="0.2"  
        android:fromYScale="0.2"  
        android:pivotX="50%"  
        android:pivotY="50%"  
        android:toXScale="1.5"  
        android:toYScale="1.5" />  
  
    <rotate  
        android:duration="1000"  
        android:fromDegrees="0"  
        android:repeatCount="1"  
        android:repeatMode="reverse"  
        android:toDegrees="360" />  
  
    <translate  
        android:duration="2000"  
        android:fromXDelta="0"  
        android:fromYDelta="0"  
        android:toXDelta="320"  
        android:toYDelta="0" />  
  
    <alpha  
        android:duration="2000"  
        android:fromAlpha="1.0"  
        android:toAlpha="0.1" />  

</set>  

3.写个例子来体验下

好的,下面我们就用上面写的动画来写一个例子,让我们体会体会何为补间动画: 首先来个简单的布局:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_alpha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="透明度渐变" />

    <Button
        android:id="@+id/btn_scale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="缩放渐变" />

    <Button
        android:id="@+id/btn_tran"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位移渐变" />

    <Button
        android:id="@+id/btn_rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="旋转渐变" />

    <Button
        android:id="@+id/btn_set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="组合渐变" />

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        android:src="@mipmap/img_face" />
    
</LinearLayout>

好哒,接着到我们的MainActivity.java,同样非常简单,只需调用AnimationUtils.loadAnimation() 加载动画,然后我们的View控件调用startAnimation开启动画即可~

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_alpha;
    private Button btn_scale;
    private Button btn_tran;
    private Button btn_rotate;
    private Button btn_set;
    private ImageView img_show;
    private Animation animation = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        btn_alpha = (Button) findViewById(R.id.btn_alpha);
        btn_scale = (Button) findViewById(R.id.btn_scale);
        btn_tran = (Button) findViewById(R.id.btn_tran);
        btn_rotate = (Button) findViewById(R.id.btn_rotate);
        btn_set = (Button) findViewById(R.id.btn_set);
        img_show = (ImageView) findViewById(R.id.img_show);

        btn_alpha.setOnClickListener(this);
        btn_scale.setOnClickListener(this);
        btn_tran.setOnClickListener(this);
        btn_rotate.setOnClickListener(this);
        btn_set.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_alpha:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_alpha);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_scale:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_scale);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_tran:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_translate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_rotate:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_rotate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_set:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_set);
                img_show.startAnimation(animation);
                break;
        }
    }
}

运行效果图

嘿嘿,有点意思是吧,还不动手试试,改点东西,或者自由组合动画,做出酷炫的效果吧~


4.动画状态的监听

我们可以对动画的执行状态进行监听,调用动画对象的:

  • setAnimationListener(new AnimationListener())方法,重写下面的三个方法:
  • onAnimationStart():动画开始
  • onAnimtaionRepeat():动画重复
  • onAnimationEnd():动画结束

即可完成动画执行状态的监听~


5.为View动态设置动画效果

先调用AnimationUtils.loadAnimation(动画xml文件),然后View控件调用startAnimation(anim) 开始动画~这是静态加载的方式,当然你也可以直接创建一个动画对象,用Java代码完成设置,再调用 startAnimation开启动画~


6.为Fragment设置过渡动画

这里要注意一点,就是Fragment是使用的v4包还是app包下的Fragment! 我们可以调用FragmentTransaction对象的setTransition(int transit) 为Fragment指定标准的过场动画,transit的可选值如下:

  • TRANSIT_NONE:无动画
  • TRANSIT_FRAGMENT_OPEN:打开形式的动画
  • TRANSIT_FRAGMENT_CLOSE:关闭形式的动画

上面的标准过程动画是两个都可以调用的,而不同的地方则在于自定义转场动画

setCustomAnimations()方法!

  • app包下的Fragment: setCustomAnimations(int enter, int exit, int popEnter, int popExit) 分别是添加,移除,入栈,以及出栈时的动画! 另外要注意一点的是,对应的动画类型是:属性动画(Property),就是动画文件 的根标签要是:<objectAnimator>,<valueAnimator>或者是前面两者放到一个<set>里;

  • v4包下的Fragment: v4包下的则支持两种setCustomAnimations()

另外要注意一点的是,对应的动画类型是:补间动画(Tween),和上面的View一样~

可能你会有疑惑,你怎么知道对应的动画类型,其实只要你到Fragment源码那里找下:

onCreateAnimation()方法的一个返回值就知道了:

v4包

app包


7.为Activity设置过场动画

Activty设置过场动画非常简单,调用的方法是:overridePendingTransition(int enterAnim, int exitAnim)

用法很简单:在startActivity(intent)或者finish()后添加

参数依次是:新Activity进场时的动画,以及旧Activity退场时的动画

下面提供几种比较简单而且常用的过场动画供大家使用~

下载传送门:Activity常用过渡动画.zip


8.写个进入APP后登陆注册按钮从底部弹出动画效果的例子:

运行效果图

代码实现

首先是我们的布局文件:activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DDE2E3"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/start_ctrl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical"
        android:visibility="gone">

        <Button
            android:id="@+id/start_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#F26968"
            android:gravity="center"
            android:paddingBottom="15dp"
            android:paddingTop="15dp"
            android:text="登陆"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />

        <Button
            android:id="@+id/start_register"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#323339"
            android:gravity="center"
            android:paddingBottom="15dp"
            android:paddingTop="15dp"
            android:text="注册"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />
    </LinearLayout>

</RelativeLayout>

接着是MainActivity.java

public class MainActivity extends AppCompatActivity {
    private LinearLayout start_ctrl;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start_ctrl = (LinearLayout) findViewById(R.id.start_ctrl);
        //设置动画,从自身位置的最下端向上滑动了自身的高度,持续时间为500ms
        final TranslateAnimation ctrlAnimation = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, 1, TranslateAnimation.RELATIVE_TO_SELF, 0);
        ctrlAnimation.setDuration(500l);     //设置动画的过渡时间
        start_ctrl.postDelayed(new Runnable() {
            @Override
            public void run() {
                start_ctrl.setVisibility(View.VISIBLE);
                start_ctrl.startAnimation(ctrlAnimation);
            }
        }, 2000);
    }
}

注释写得很清楚了,这里就不BB解释了,如果你对TranslateAnimation.RELATIVE_TO_SELF这个有疑惑, 请自己谷歌或者百度,限于篇幅,这里就不写了。

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

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

相关文章

提示计算机丢失MSVCP140.dll怎么办?这三个修复方法可解决

最近在使用电脑的过程中&#xff0c;遇到了一个问题&#xff0c;即缺少了MSVCP140.dll文件。这个文件是一个动态链接库文件&#xff0c;常用于Windows操作系统中的应用程序中。由于缺少这个文件&#xff0c;会导致计算机系统无法运行某些软件或游戏。丢失MSVCP140.dll可能是由于…

【技术分享】oracle数据库相关操作

-- 截断表 TRUNCATE TABLE TABLE_NAME;-- 删除表 DROP TABLE TABLE_NAME;-- 查询表 SELECT * FROM TABLE_NAME;-- 添加一条记录 INSERT INTO TABLE_NAME(COLUMN) VALUES(VALUE);-- 删除记录 DELETE FROM TABLE_NAME WHERE COLUMNVALUE;-- 修改记录 UPDATE TABLE_NAME SET…

Android性能优化之Thread native层源码分析(InternalError/Out of memory)

近期处理Bugly上OOM问题&#xff0c;很多发生在Thread创建启动过程&#xff0c;虽然最后分析出是32位4G虚拟内存不足导致&#xff0c;但还是分析下Java层Thread 源码过程&#xff0c;可能会抛出的异常InternalError/Out of memory。 Thread报错堆栈&#xff1a; Java线程创建…

数据库|手把手教你成为 TiDB 的 Contributor

一、背景 最近笔者在 AskTUG 回答问题的时候发现&#xff0c;在 6.5.0 版本出现了几个显示未启动必要组件 NgMonitoring 的问题贴。经过排查发现&#xff0c;是 ngmonitoring.toml 中的配置文件出现了问题。文件中的 endpoints 应该是以逗号分隔的&#xff0c;但是却写成了以空…

JavaWeb 项目实现(二) 注销功能

3.注销功能 接前篇&#xff0c;实现了登录功能之后&#xff0c;现在实现注销功能。 因为我们实现登录就是在Session中记录了用户信息。 所以注销功能&#xff0c;就是在Session中移除用户信息。 代码&#xff1a;删除Session中的用户信息&#xff0c;跳转登录页面 package…

【安全渗透】第一次作业(编码知识总结)

目录 1. ASCII编码 2、Unicode 3、UTF-8 1. ASCII编码 ASCII 是“American Standard Code for Information Interchange”的缩写&#xff0c;翻译过来是“美国信息交换标准代码”。ASCII 的标准版本于 1967 年第一次发布&#xff0c;最后一次更新则是在 1986 年&#xff0c…

QEMU源码全解析13 —— QOM介绍(2)

接前一篇文章&#xff1a;QEMU源码全解析12 —— QOM介绍&#xff08;1&#xff09; 本文内容参考&#xff1a; 《趣谈Linux操作系统》 —— 刘超&#xff0c;极客时间 《QEMU/KVM》源码解析与应用 —— 李强&#xff0c;机械工业出版社 特此致谢&#xff01; 本回开始对QOM…

django学习笔记(1)

django创建项目 先创建一个文件夹用来放django的项目&#xff0c;我这里是My_Django_it 之后打开到该文件下&#xff0c;并用下面的指令来创建myDjango1项目 D:\>cd My_Django_itD:\My_Django_it>"D:\zzu_it\Django_learn\Scripts\django-admin.exe" startpr…

记录每日LeetCode 2500.删除每行中的最大值 Java实现

题目描述&#xff1a; 给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。 将删除元素中的最大值与答案相加。 …

Reinforcement Learning with Code 【Chapter 7. Temporal-Difference Learning】

Reinforcement Learning with Code This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation of Reinforcement Learning, . 文章…

Linux内核与内核空间是什么关系呢?

对内核空间的认识清晰了许多。要理解用户空间与内核空间需要有如下的几个认识&#xff1a; 内核的认识&#xff1a;从2个不同的角度来理解&#xff0c;一个是静态的角度&#xff0c;如“芦中人”所比喻&#xff0c;内核可以看做是一个lib库&#xff0c;内核对外提供的API打包…

快速远程桌面控制公司电脑远程办公

文章目录 快速远程桌面控制公司电脑远程办公**第一步****第二步****第三步** 快速远程桌面控制公司电脑远程办公 远程办公的概念很早就被提出来&#xff0c;但似乎并没有多少项目普及落实到实际应用层面&#xff0c;至少在前几年&#xff0c;远程办公距离我们仍然很遥远。但20…

1分钟上手Apifox

1、客户端右上角账号设置-生成令牌 2、IDEA下载插件 Apifox Helper 3、 配置ApiFoxHelper 令牌 4、在controller类界面右键 5、输入项目id 6、项目ID从客户端 项目设置-项目ID获取 7、导入成功 8、右键刷新查看导入的接口 9、自动生成数据&#xff08;某postman还要自己手输&a…

说一说java中的自定义注解之设计及实现

一、需求背景 比如我们需要对系统的部分接口进行token验证&#xff0c;防止对外的接口裸奔。所以&#xff0c;在调用这类接口前&#xff0c;先校验token的合法性&#xff0c;进而得到登录用户的userId/role/authority/tenantId等信息&#xff1b;再进一步对比当前用户是否有权…

MyBatis 快速入门【中】

&#x1f600;前言 本篇博文是MyBatis(简化数据库操作的持久层框架)–快速入门[上]的核心部分&#xff0c;分享了MyBatis实现sql的xml配置和一些关联配置、异常分析 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&a…

软件外包开发的需求分析

需求分析是软件开发中的关键步骤&#xff0c;其目的是确定用户需要什么样的软件&#xff0c;以及软件应该完成哪些任务。需求分析是软件工程的早期工作&#xff0c;也是软件项目成功的基础&#xff0c;因此花费大量精力和时间去做好需求分析是值得的。今天和大家分享软件需求分…

数字孪生-数字城市效果实现方法

数字孪生-数字城市效果实现方法 效果图&#xff1a; 一、效果分析&#xff1a; .0 1、城市非主展示区域白模快速生成方案&#xff1a; 参考视频&#xff1a; 1、CityEngine 引用数据源生成。 cityengine2022一键生成城市模型&#xff0c;不用再用blendergis_哔哩哔哩_bil…

Python运算符列表及其优先顺序、结合性

本文表格对Python中运算符的优先顺序进行了总结&#xff0c;从最高优先级&#xff08;最先绑定&#xff09;到最低优先级&#xff08;最后绑定&#xff09;。相同单元格内的运算符具有相同优先级。除非句法显式地给出&#xff0c;否则运算符均指二元运算。 相同单元格内的运算…

数据安全之全景图系列——数据分类分级落地实践

1、数据分类分级现状 我们正处于一个数据爆炸式增长的时代&#xff0c;随着产业数字化转型升级的推进&#xff0c;数据已被国家层面纳入生产要素&#xff0c;并且成为企业、社会和国家层面重要的战略资源。数据分类分级管理不仅是加强数据交换共享、提升数据资源价值的前提条件…

Unreal MorphTarget Connect Bone MetaData Curve功能学习

MorphTarget Connected Bone和MetaData Curve是两个较冷门功能&#xff0c;近期在制作一些功能时留意到这2个内容&#xff0c;故研究一下。 1.MorphTarget Connected Bone 在骨架编辑面板中&#xff0c;选中MorphTarget时&#xff0c;可找到Connected Bone选项&#xff1a; …