爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Android中的动画

      首页 知识中心 其他 文章详情页

      Android中的动画

      2024-06-17 09:52:23 阅读次数:42

      android

      学习内容

      Ø 帧动画

      Ø 补间动画

      Ø 动画方式切换组件

      能力目标

      Ø 掌握Android中动画的基本概念及分类

      Ø 熟练掌握帧动画的实现

      Ø 熟练掌握各种补间动画的实现

      Ø 掌握如何使用动画方式实现组件之间的切换效果


      本章简介

      在Android程序设计过程中,除了使用简单的按钮、文本框等简单控件来构建基本界面,我们还可以通过为界面添加动画效果,使得界面更加变得更加绚丽,更加吸引人。Android平台也提供了一套完整的动画框架,使得开发者可以用它开发出各种动画效果。

      本章主要介绍Android系统中的动画:帧动画和补间动画。其中帧动画使用AnimationDrawable来实现,在本质上是将多个图像以相同或不同的时间间隔进行切换来实现动画。补间动画需要指定动画开始和结束状态,然后由系统自动生成中间状态的图像,它包括移动、缩放、旋转、透明度的变化等。除此之外我们还将学习Android默认提供的accelerate_interpolator、decelerate_interpolator、accelerate_decelerate_interpolator等多种动画渲染器。

      2.1 Android中的动画

      Android中的Animations动画效果多种多样,其中包括旋转、缩放、淡入淡出等,这些效果可以应用于绝大多数的控件(图片、按钮、文本)。总的来说,默认Android系统主要提供以下两类动画:

      Ø 帧动画(Frame-By-Frame Animations):通过顺序播放事先做好的图像来实现动画效果,和电影相似。

      Ø 补间动画(Tweened Animations):通过对场景里的对象不断进行图像变换(平移、缩放、旋转)来产生动画效果。具体来讲,Tween动画是通过预先定义一组指令(这组指令指定了图形变换类型、触发时间、持续时间等),程序沿着时间轴执行这些指令来实现动画效果。

      2.2 帧动画

      在Android系统中大多数免费应用都会在界面中添加广告以取得收入,而多数广告都如我们经常看到的GIF图片那样,几张不同的图片不断变换以增加广告内容的充实度,而这里就需要我们使用帧动画技术来实现这些效果。

      帧动画实际上是由若干个以一定的时间间隔进行切换的图像组成的。比如电影的原理就类似于帧动画,一般电影是每秒25帧。即,电影在每秒钟之内会以相等的时间间隔连续播放25幅静态画面,由于人的视觉暂留,在这样的播放频率下,看起来这些画面好像是连续的。在第一章中我们在onDraw()方法中使用invalidate()方法不断地刷新View的方式实现的旋转动画,这种情况下,是不断地画出动画中的每一帧图像,它其实也相当于帧动画。

      要在Android中实现帧动画,首先需要在res/anim目录下创建一个后缀为.xml的动画文件。然后在这个文件中指定动画中的静态图像和每一张静态图像的停留时间,这个时间的单位是毫秒。为了让用户看起来舒服,一般可以将所有的图像停留时间设为同一个值。动画文件的一般形式如下。

      <animation-list android:oneshot="false"

      xmlns:android="http:///apk/res/android"> 

      <item android:duration="500" android:drawable="@drawable/a1"/> 

      <item android:duration="500" android:drawable="@drawable/a2"/> 

      ……

      </animation-list>

      一般情况下,动画文件由一个<animation-list>标签和若干个<item>标签组成。其中<animation-list>标签的android:oneshot属性取值为true时表示动画只运行一遍,为false时动画会循环播放,这个属性是可选的,默认值是false。<item>标签的android:drawable属性    用来指定动画中静态图像资源的ID,android:duration用来指定每个图像的停留时间,这两个属性都是必选的,缺一不可。

      编写完动画文件之后,就需要装载动画文件,并创建AnimationDrawable对象。AnimationDrawable是Drawable的子类,它在Drawable的基础之上提供了控制动画的功能。

      实现帧动画的基本步骤是:

      (1) 在drawable中插入一系列的图片,注意这里面图片的命名最好要有规律可循,以方便编程使用,例如我这里面的命名是a1、a2……。

      (2) 在res/anim文件夹当中创建一个xml类型的文件,将所有帧都列出来以定义Animations动画序列,在此处可以通过oneshot设置动画是否重复播放。

      示例2.1:

      实现GIF动画的播放效果。

      在屏幕上提供一个ImageView和四个Button,当用户单击这些Button按钮时,依次实现“开始动画”、“停止动画”、“运行一次动画”、“代码中添加动画”的功能。其中ImageView组件的作用是按照我们在动画文件中设置的顺序显示res/drawable目录下的静态图片。整个程序运行的效果和GIF图像基本一样。整下程序的运行效果如下图2.1.1和图2.1.2所示:

      Android中的动画

      Android中的动画

      (1)编写动画文件代码如下:

      <animation-list android:oneshot="false"

      xmlns:android="http:///apk/res/android"> 

       

      <item android:duration="500" android:drawable="@drawable/a1"/> 

      <item android:duration="500" android:drawable="@drawable/a2"/> 

      <item android:duration="500" android:drawable="@drawable/a3"/> 

      <item android:duration="500" android:drawable="@drawable/a4"/> 

      <item android:duration="500" android:drawable="@drawable/a5"/> 

      <item android:duration="500" android:drawable="@drawable/a6"/> 

      <item android:duration="500" android:drawable="@drawable/a7"/> 

      <item android:duration="500" android:drawable="@drawable/a8"/>

       

      </animation-list>

      (2)编写程序布局文件,在布局文件中只是提供一个id为imageViewId的ImageView组件和四个id分别为btn1、btn2、btn3、btn4的Button组件。

      (3)编写Activity类,实现功能代码如下:

      public class FrameByFrameActivity extends Activity {

      private ImageView imageView =null;

      private AnimationDrawable drawable = null;

       

          @Override

          public void onCreate(Bundle savedInstanceState) {

              super.onCreate(savedInstanceState);

              setContentView(R.layout.framebyframe);

              

              imageView = (ImageView) findViewById(R.id.imageViewId);

              

              //开始动画

              Button btn = (Button) findViewById(R.id.btn1);

              btn.setOnClickListener(new View.OnClickListener() {

      public void onClick(View v) {

      //装载动画布局文件

      imageView.setBackgroundResource(R.anim.framebyframe);

      //构建动画

      AnimationDrawable drawable = null;

      drawable=(AnimationDrawable) imageView.getBackground();

      //开始播放动画

      drawable.start();

      }

      });

              //停止动画

              Button btn2 = (Button) findViewById(R.id.btn2);

              btn2.setOnClickListener(new View.OnClickListener() {

      public void onClick(View v) {

      drawable.stop();

      }

      });

              

              //运行一次动画

              Button btn3 = (Button) findViewById(R.id.btn3);

              btn3.setOnClickListener(new View.OnClickListener() {

      public void onClick(View v) {

      drawable.setOneShot(true);

      drawable.start();

      }

      });

              //添加动画

              Button btn4 = (Button) findViewById(R.id.btn4);

              btn4.setOnClickListener(new View.OnClickListener() {

      public void onClick(View v) {

      //装载动画布局文件

       

      //AnimationDrawable对象用来表示Frame动画

      AnimationDrawable frameDrable = new AnimationDrawable();

      Drawable drawable = null;

      //装载资源

      for(int i = 1 ; i <10 ;i++){

      int id = getResources().getIdentifier("a"+i, "drawable", getPackageName());

      drawable = getResources().getDrawable(id);

      frameDrable.addFrame(drawable, 1000);//把每一帧要显示的内容添加进去

      }

      //设置动画不重复播放

      frameDrable.setOneShot(false);

      imageView.setBackgroundDrawable(frameDrable);

      //开始播放动画

      frameDrable.start();

      }

      });

              

          }

      }

       

      在btn1按钮的单击事件中,我们实现了动画文件的装载、AnimationDrawable的构建及动画的播放功能。

      除了示例代码中使用ImageView的setBackgroundResource()方法来装载动画文件,并通过ImageView的getBackground()方法获得AnimationDrawable对象实现动画效果之外,我们还可以使用getDrawable()方法来装载动画文件,代码如下:

      AnimationDrawable drawable =

      (AnimationDrawable) getResources().getDrawable(R.anim.framebyframe);

      imageView.setBackgroundDrawable(drawable);

      在btn4按钮的单击事件中,我们先通过new关键字声明了一个AnimationDrawable对象,然后利用Java代码通过循环的方式为这个对象添加了一系列的静态图片。最后调用start()方法让其运动起来。

      通过上述代码我们会发现,所有对帧动画的控制都是通过AnimationDrawable实现的。本示例程序中用到的AnimationDrawable中与帧动画有关的方法如下:

      Ø start():开始播放动画

      Ø stop():停止播放动画

      Ø void setOneShot(boolean  b):

      设置是否只播放一遍帧动画。这个方法的参数与动画文件中的<animation-list>标签的android:oneshot属性值的含义相同。

      Ø void  addFrame(Drawable frame, int duration)

      向AnimationDrawable对象中添加新的帧。其中参数frame是一个Drawable对象,表示要添加的帧,该参数可以是静态图像,也可以是另一个动画。参数duration表示帧动画的停留时间,如果新添加的帧是动画,那么这停留时间就是新添加的动画可以播放的时间,如果到了停止时间,不管新添加的动画是否播放完,都会切换到下一个静态图像或动画。

      2.3 补间动画

      通过上述的帧动画(Frame-By-Frame Animations)技术,我们可以方便的制作出如flash般的动画效果,只需要我们准备好每一帧动画所需要的画面,然后按照组织好的顺序使其顺序播放,即可达到动画片似的效果,但是,如果仅仅是一个物体的简单移动,放大缩小等功能,我们依然需要为其准备不同时刻的静态画面,按照电影一秒内播放25帧的速度,四秒时长的动画效果我们就需要为其准备多达100张静态图片,这样看来依然过于繁琐,而对于这种简单的移动、放大缩小、旋转等动画效果,安卓系统也为我们提供了更加方便的动画生成技术,我们称之为补间动画(Tweened Animations)。

      补间动画(Tweened Animations)是指在制作动画过程中,开发者只用定义动画的开始、结束等等关键帧信息,中间的变化效果由系统自动生成,所以称之为补间动画。

      对于图像的简单移动、旋转、缩放等,都可以通过补间动画来实现。然而,当图像过于复杂时,由于系统无法预料下一幅画面的样子,此时不宜采用补间动画,要实现动画效果只能采用帧动画的形式。

      因为补间动画只需要提供两帧图像(第一帧和最后一帧),并指定动画的持续时间即可。所以补间动画最大的优点是节省硬盘空间。

      Android中使用Animation类代表抽象的动画类,它包含以下几个子类:

      Ø TranslateAnimation:位移变化的动画,创建该动画时只要指定动画开始时的位置(以X、Y坐标来表示)、结束时的位置(以X、Y坐标来表示),并指定动画持续的时间即可。

      Ø RotateAnimation:旋转动画,创建该动画时只要指定动画开始时的旋转角度、结束时的旋转角度,并指定动画持续的时间即可。由于旋转时以不同点为中心时旋转效果并不相同,因此指定旋转动画时还要指定“旋转中心”的坐标。

      Ø ScaleAnimation:缩放动画,创建该动画时要指定动画开始时的缩放比(以X、Y轴的缩放参数表示)、结束时动画的缩放比以X、Y轴的缩放参数表示),并指定动画持续的时间。由于旋转时以不同点为中心时缩放效果并不相同,因此指定缩放动画时还要指定“缩放中心”的坐标。

      Ø AlphaAnimation:透明度改变动画,创建该动画时需要指定动画开始时的透明度、结束时的透明度和动画持续时间,其中透明度的变化范围是1~0。

      在本节中我们将通过具体的案例深入学习Android系统默认提供的移动、缩放、旋转和透明四种补间动画效果。

      2.3.1 移动补间动画

      《水果忍者》也许很多同学都玩过,游戏中玩家需要用手指模拟武士刀将上抛起的各种水果切开,那么这种水果上下移动的动画效果如何实现呢?这里我们就可以使用移动补间动画来实现。

      移动是最常见的动画效果,可以通过配置文件或Java代码文件来实现。

      示例2.2

      上下跳动的小球。

      在手机屏幕上显示一下上下移动的小球,用来模拟物体的自由下落:当小球从上到下移动时呈现加速状态,从下到上移动时呈现减速状态。

      补间动画文件放在res/anim目录中,在动画文件中通过<translate>标签设置移动的效果。本示例用到两个动画渲染器:accelerate_interpolator、decelerate_interpolator。首先定义具体动画的文件。

      translatescaletop.xml定义从下到上移动,减速效果。

      <?xml version="1.0" encoding="utf-8"?>

      <translate xmlns:android="http:///apk/res/android"

          android:interpolator="@android:anim/accelerate_interpolator"

          android:fromXDelta="0"

          android:toXDelta="0"

          android:fromYDelta="250"

          android:toYDelta="0"

          android:duration="2200" />

      translatebottom.xml定义从上到下移动,加速效果。

      <?xml version="1.0" encoding="utf-8"?>

      <translate xmlns:android="http:///apk/res/android"

          android:interpolator="@android:anim/ decelerate_interpolator"

          android:fromXDelta="0"

          android:toXDelta="0"

          android:fromYDelta="0"

          android:toYDelta="250"

      android:duration="2200" />

      <translate>标签中设置了几个属性,这些属性的含义如下:

      Ø android:interpolator:表示动画渲染器, Android系统一共为我们提供了linear_interpolator、accelerate_interpolator(动画加速器)、decelerate_interpolator(动画减速器)和accelerate_decelerate_interpolator(动画加速减速器)四种动画渲染器,其中动画加速减速器使动画在开始和结束时速度很慢,但在前半部分开始加速,后半部分开始减速。

      Ø android:fromXDelta:动画起始位置的横坐标。

      Ø android:toXDelta:动画结束位置的横坐标。

      Ø android:fromYDelta:动画起始位置的纵坐标。

      Ø android:toYDelta:动画结束位置的纵坐标。

      Ø android:duration:动画持续的时间。

      Activity类代码如下:

      public class BallAnimationsActivity extends Activity implements AnimationListener {

      private ImageView imageView = null;

      private Animation animationBottom;//从上到下

      private Animation animationTop;//从下到上

       

      @Override

      protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.ballanimations);

       

      imageView = (ImageView) findViewById(R.id.imageview);

      Button button = (Button) findViewById(R.id.button);

       

      button.setOnClickListener(new OnClickListener() {

      @Override

      public void onClick(View v) {

      imageView.startAnimation(animationBottom);

      }

      });

       

      animationBottom = AnimationUtils.loadAnimation(this, R.anim.transloatebottom);

      animationTop = AnimationUtils.loadAnimation(this, R.anim.transloatetop);

       

      animationBottom.setAnimationListener(this);

      animationTop.setAnimationListener(this);

      }

       

      @Override

      public void onAnimationStart(Animation animation) {

      //动画开始时调用

      }

       

      @Override

      public void onAnimationEnd(Animation animation) {//动画结束时调用

      //根据当前显示的动画决定下次显示哪一个动画

      if (animation.hashCode() == animationBottom.hashCode())

      imageView.startAnimation(animationTop);

      else if (animation.hashCode() == animationTop.hashCode())

      imageView.startAnimation(animationBottom);

      }

       

      @Override

      public void onAnimationRepeat(Animation animation) {//动画循环时调用

       

      }

      }

      代码解析:

      其中ballanmimations.xml是一个只提供了一个包含id为imageView的ImageView组件和一个id为btn的Button组件的布局文件。

      补间动画有动画开始、动画结束、动画循环3种状态:,我们可以通过android.view.animation.Animation.AnimationListener接口实现对这三种状态的监听。这个接口中定义的三个方法:onAnimationStart()、onAnimationEnd()、onAnimationRepeat()分别在动画开始、动画结束和动画循环时被调用。

      将动画文件应用到指定的组件上,除了可以使用示例中调用startAnimation()方法外,还可以使用如下方法:

      imageView.setAnimation(animationBottom);

      animation.start();

      程序中装载动画文件时用到了如下方法:

      Animation  AnimationUtils.loadAnimation(Context context, int id)

      从资源文件中装载动画。其中id表示动画文件的资源ID。

      单击【开始动画】按钮后,小球就会在垂直方向上按照我们的设置上下移动,效果如下图2.1.3所示。

      Android中的动画

      2.3.2 缩放补间动画

      在《愤怒的小鸟》的游戏中,当我们需要让小鸟由远及近或者由近及远飞翔时,那么它应该是出现一种由小变大或者由大变小的状态来模拟距离的改变,而这种动画的实现,我们就需要用到下面的缩放补间动画技术。

      示例2.3:

      实现一个可以跳动的心.跳动实际上就是不断地将心型的图像放大和缩小,因此本示例需要两个动画文件,一个表示放大后的状态,一个表示缩小后的状态。

      心脏放大的配置文件scalelarge.xml代码如下:

      <scale xmlns:android="http:///apk/res/android"

          android:duration="500"

          android:fromXScale="0.2"

          android:toXScale="1.0"

          android:fromYScale="0.2"

          android:toYScale="1.0" 

          android:interpolator="@android:anim/decelerate_interpolator"

          android:pivotX="50%"

          android:pivotY="50%" />

      心脏缩小的配置文件scalesmall.xml代码如下:

      <scale xmlns:android="http:///apk/res/android"

          android:duration="500"

          android:fromXScale="1.0"

          android:fromYScale="1.0"

          android:interpolator="@android:anim/accelerate_interpolator"

          android:pivotX="50%"

          android:pivotY="50%"

          android:toXScale="0.2"

      android:toYScale="0.2" />

      <scale>标签中设置了几个属性,这些属性的含义如下:

      Ø android:fromXScale:表示沿X轴缩放的起始比例。

      Ø android:toXScale:表示沿X轴缩放的结束比例。

      Ø android:fromYScale:表示沿Y轴缩放的起始比例。

      Ø android:toYScale:表示沿Y轴缩放的结束比例。

      Ø android:pivotX:表示沿X轴方向上缩放的中心点位置。

      Ø android:pivotY:表示沿Y轴方向上缩放的中心点位置。

      接下来在Activity中编写功能实现代码。

      public class HeartScaleActivity extends Activity implements AnimationListener {

      private Animation large;

      private Animation small;

      private ImageView imageView;

      @Override

      public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.heartanimations);

      imageView = (ImageView) findViewById(R.id.imageview);

      large = AnimationUtils.loadAnimation(this, R.anim.scalelarge);

      small = AnimationUtils.loadAnimation(this, R.anim.scalesmall);

      large.setAnimationListener(this);

      small.setAnimationListener(this);

       

      imageView.startAnimation(small);

      }

       

      @Override

      public void onAnimationEnd(Animation animation) {

      if (animation.hashCode() == large.hashCode())

      imageView.startAnimation(small);

      else

      imageView.startAnimation(large);

       

      }

      @Override

      public void onAnimationRepeat(Animation animation) {

      }

       

      @Override

      public void onAnimationStart(Animation animation) {

      }

      }

      其中heartanmimations.xml是一个只提供了一个包含id为imageView的ImageView布局文件。

      任意选取两个时刻,程序运行效果如下图2.1.4和图2.1.5所示。

       

      图2.1.4 心形放大的图像

       

      图2.1.5 心型缩小图像

      2.3.3 旋转补间动画

      在游戏中,很多时候我们要实现某个物品按照某个点不断旋转的效果,例如《疯狂的小鸟》游戏中,当小鸟撞上障碍物时,就会不断旋转着跌落下去,这里小鸟的运动显然除了旋转,还有一个自由落体的运动过程,而单就旋转这种简单的动画来说,我们就可以运用Android系统中提供的旋转补间动画来实现。

      示例2.4:模拟实现月球环绕地球旋转的效果,如下图2.1.6所示。

       

      图2.1.6 地月系

      定义地球自转动画的xml文件earth.xml内容如下:

      <rotate xmlns:android="http:///apk/res/android"

          android:duration="20000"

          android:fromDegrees="0"

          android:pivotX="50%"

          android:pivotY="50%"

      android:repeatCount="infinite"

      android:repeatMode="restart"

          android:toDegrees="360" />

      定义月球围绕地球旋转动画的xml文件moon.xml内容如下:

      <rotate xmlns:android="http:///apk/res/android"

          android:duration="10000"

          android:fromDegrees="0"

          android:pivotX="200%"

          android:pivotY="300%"

          android:repeatCount="infinite"

          android:repeatMode="restart"

          android:toDegrees="360" />

      <rotate>标签中设置了几个属性,这些属性的含义如下:

      Ø android: fromDegrees:表示旋转的起始角度。

      Ø android:toDegrees:表示旋转的结束角度。

      Ø android:repeatCount:用来设置旋转的次数。当取值为0时(默认),从0度旋转到360度,动画就会停止;如果属性值为N(N>0),动画会不停地显示N+1次;当取值为infinite或-1时,动画会永不停地运行下去。

      Ø android:repeatMode:用来设置旋转的模式。默认值是restart,该属性值只有当android:repeatCount设置成大于0的数或infinite时才起作用。该属性取值reverse时表示偶数次显示动画时会做与动画文件定义的方向相反的动作。

      Ø pivotX:旋转支点横坐标。

      Ø pivotY:旋转支点纵坐标。

      pivotX和pivotY的取值有两种:float或百分数,分别是相对于物体左(上)边距的像素表示或相对于物体左(上)边距的百分数表示。旋转支点坐标的具体计算公式如下:

      假如物体原来的坐标是(x0,y0),采用像素形式时pivotX=x1,pivotY=y1,采用百分比形式时pivotX=n1%,pivotY=n2%。那么最终旋转中心的坐标为(x0+x1,y0+y1)或(x0+width*n1%,y0+height*n2%),其中width和height分别指图片的宽度和高度。

       

      Activity类代码:

      public class EarthMoonActivity extends Activity {

      @Override

      public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.earthmoon);

       

      ImageView moon = (ImageView) findViewById(R.id.moon);

      ImageView earth = (ImageView) findViewById(R.id.earth);

       

      Animation moonAnimation = AnimationUtils.loadAnimation(this, R.anim.moon);

      Animation earthAnimation = AnimationUtils.loadAnimation(this, R.anim.earth);

       

      moon.startAnimation(moonAnimation);

      earth.startAnimation(earthAnimation);

      }

      }

      其中布局文件earthmoon.xml采用绝对布局,在其中放置了两个id分别为moon和earth的ImageView组件,详细代码如下:

      <?xml version="1.0" encoding="utf-8"?>

      <AbsoluteLayout xmlns:android="http:///apk/res/android"

          android:layout_width="fill_parent"

          android:layout_height="fill_parent"

          android:gravity="center_vertical"

          android:orientation="vertical" >

          <ImageView

              android:id="@+id/moon"

              android:layout_width="50dp"

              android:layout_height="50dp"

              android:layout_x="50dp"

              android:layout_y="50dp"

              android:src="@drawable/moon" />

          <ImageView

              android:id="@+id/earth"

              android:layout_width="80dp"

              android:layout_height="80dp"

              android:layout_x="120dp"

              android:layout_y="200dp"

              android:src="@drawable/ball" />

      </AbsoluteLayout>

      运行程序,会发现代表月亮的图片会按照逆时针方向围绕着地球旋转,而地球本身也会按照顺时针的方向围绕着自身的地轴旋转。

      2.3.4 透明补间动画

      很多游戏在设计时,都会让已经被消灭的敌人慢慢地在屏幕中变成透明状,最后完全消失,以避免挤占宝贵的屏幕显示资源,而在Android系统中,这种效果同样十分简单,只需要运用我们下面提到的这种技术即可——透明补间动画。

      示例2.5:

      通过改变图片透明度实现屏幕上对象逐渐消失的效果。

      动画效果定义文件alpha.xml内容如下:

      <?xml version="1.0" encoding="utf-8"?>

      <set xmlns:android="http:///apk/res/android"

      android:interpolator="@android:anim/accelerate_interpolator"

      android:shareInterpolator = "true">

      <alpha

      android:fromAlpha="1.0"

      android:toAlpha = "0.0"

      android:startOffset= "200"

      android:duration = "3000"

      />

      </set>

      这个文件定义中各个属性含义如下:

      Ø android:fromAlpha:表示起始透明度,取值在0.0~1.0之间,其中0.0表示完全透明,1.0表示完全不透明。

      Ø android:toAlpha:表示结束透明度。

      Ø android:shareInterpolator = "true":设置内部所有的控件共享Interpolator。

      Ø android:startOffset:开始时间偏移量,指在动画开始前等待的时间。

      布局文件代码:

      <?xml version="1.0" encoding="utf-8"?>

      <AbsoluteLayout xmlns:android="http:///apk/res/android"

          android:layout_width="fill_parent"

          android:layout_height="fill_parent"

          android:gravity="center_vertical"

          android:orientation="vertical" >

          <ImageView

              android:id="@+id/earth"

              android:layout_width="80dp"

              android:layout_height="80dp"

              android:layout_x="120dp"

              android:layout_y="100dp"

              android:src="@drawable/ball" />

      </AbsoluteLayout>

      Activity类代码:

      public class EarthMoonActivity extends Activity {

      @Override

      public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.earthmoon);

       

      ImageView earth = (ImageView) findViewById(R.id.earth);

       

      Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha);

      earth.startAnimation(animation);

      }

      }

      某一时刻程序的运行效果如下图2.1.7所示:

      图2.1.7 透明效果

      2.4 动画方式切换各组件

      最后让我们将上述提到的几种技术融合在一起,运用到我们的Android组件中,为Android系统组件的切换提供绚丽的动画效果。

      凡是使用过Android手机的用户,都一定会被它里面的程序组件之间的切换效果所吸引,比如Android系统自带的看图软件在各图片之间切换时的过渡效果。本节课中我们就借助android.widget.ViewFliper类来模拟实现这种过渡效果。

      示例2.6:

      实现Android中查看图片时的过渡效果。

      具体效果如下图2.1.8和2.1.9所示,第一种效果是移动切换,第二种效果是淡入淡出切换。

      图2.1.8 水平移动切换

      图2.1.9 淡入淡出切换

      本示例程序使用布局文件layout1.xml、layout2.xml、layout3.xml定义了3个View,每一个View中都包含一个用来显示图像的ImageView组件。当用户触摸第一个图像时,会以水平向左移动的方式切换到第二个图像,触摸第二个图像时会以淡入淡出的方式切换到第三个图像(通过透明度补间动画实现)。

      水平移动向左切入的动画文件translatein.xml的内容如下:

      <translate xmlns:android="http:///apk/res/android"

          android:duration="3000"

          android:fromXDelta="320"

          android:fromYDelta="0"

          android:interpolator="@anim/linear_interpolator"

          android:toXDelta="0"

          android:toYDelta="0" />

      水平移动向左切出的动画文件translateout.xml内容如下:

      <translate xmlns:android="http:///apk/res/android"

          android:duration="3000"

          android:fromXDelta="0"

          android:fromYDelta="0"

          android:interpolator="@anim/linear_interpolator"

          android:toXDelta="-320"

          android:toYDelta="0" />

      淡入淡出动画的淡入效果文件alphain.xml的内容如下:

      <alpha xmlns:android="http:///apk/res/android"

          android:duration="2000"

          android:fromAlpha="0"

          android:interpolator="@android:anim/accelerate_interpolator"

          android:toAlpha="1" />

      淡入淡出动画的淡出效果文件alphaout.xml的内容如下:

      <alpha xmlns:android="http:///apk/res/android"

          android:duration="2000"

          android:fromAlpha="1"

          android:interpolator="@android:anim/accelerate_interpolator"

      android:toAlpha="0" />

      Activity类代码如下:

      public class ViewFlipperActivity extends Activity implements OnTouchListener {

      private ViewFlipper viewFlipper;

      private Animation translateIn;

      private Animation translateOut;

      private Animation alphaIn;

      private Animation alphaOut;

      @Override

      public boolean onTouch(View view, MotionEvent event) {

      switch (view.getId()) {

      case R.id.imageview1://触摸第一个图像时:移动补间动画

      viewFlipper.setInAnimation(translateIn);

      viewFlipper.setOutAnimation(translateOut);

      break;

      case R.id.imageview2://触摸第二个图像时:透明渐变补间动画

      viewFlipper.setInAnimation(alphaIn);

      viewFlipper.setOutAnimation(alphaOut);

      break;

      }

      viewFlipper.showNext();//显示下一个View

      return false;

      }

       

      @Override

      public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      viewFlipper = (ViewFlipper) getLayoutInflater().inflate(R.layout.viewflipper, null);

      View view1 = getLayoutInflater().inflate(R.layout.layout1, null);

      View view2 = getLayoutInflater().inflate(R.layout.layout2, null);

      View view3 = getLayoutInflater().inflate(R.layout.layout3, null);

      viewFlipper.addView(view1);

      viewFlipper.addView(view2);

      viewFlipper.addView(view3);

      setContentView(viewFlipper);

      translateIn = AnimationUtils.loadAnimation(this, R.anim.translatein);

      translateOut = AnimationUtils.loadAnimation(this, R.anim.translateout);

      alphaIn = AnimationUtils.loadAnimation(this, R.anim.alphain);

      alphaOut = AnimationUtils.loadAnimation(this, R.anim.alphaout);

      ImageView imageView1 = (ImageView) view1.findViewById(R.id.imageview1);

      ImageView imageView2 = (ImageView) view2.findViewById(R.id.imageview2);

      imageView1.setOnTouchListener(this);

      imageView2.setOnTouchListener(this);

       

      }

      }

      其中布局文件viewflipper.xml的代码如下:

      <ViewFlipper xmlns:android="http:///apk/res/android"

          android:layout_width="fill_parent"

          android:layout_height="fill_parent" >

      </ViewFlipper>

      运行本程序,触摸第一幅图像会以水平移动的方式切换到第二幅图像,再次触摸第二幅图像会以淡入淡出的方式切换到第三幅图像。具体程序运行效果请参看图2.1.8和图2.1.9。

      任务实训部分 

      1:利用帧动画技术开发一个游戏人物走动的小游戏

      训练技能点

      帧动画的实现原理及技巧

      需求说明

      在任何一款游戏中,都不可避免地出现人物等对象走动的情景,结合本章所学的知识,我们可以事先提供一系列的图片,然后利用帧动画的原理实现。

      实现步骤

      具体的实现步骤请参看课本2.2节中的内容。本案例的难点是准备合适的人物行走过程中的图像,然后在动画文件中进行合适的设置。

      2: 模拟实现汽车由近到远逐渐消失的场景

      训练技能点

      Ø 移动补间动画

      Ø 缩放补间动画

      Ø 透明补间动画

      需求说明

      在我们的手机程序中会经常看到一个物体由远到近或由近到远、体积由大到小或由小到大、逐渐透明或逐渐消失的应用。比如极品飞车游戏中渐行渐远的汽车。

      本实训中要求模拟实现汽车由近到远逐渐消失的过程。汽车由近到远可通过移动补间动画实现;在消失过程中体积变小的过程可以通过缩放补间动画实现;为了增加用户的观感,可以在汽车消失的过程中为汽车设置一个透明度逐渐变化的过程,这个可通过透明补间动画实现。

      巩固练习

      一、简答题

      1. 简述实现帧动画的基本步骤。

      2. 简要描述Android默认提供的四类补间动画。

      二、上机练习

      完成一个蝴蝶振动翅膀飞动的效果,蝴蝶的振翅效果可通过逐帧动画实现,飞行时位置的改变可通过补间动画实现。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/teayear/3188750,作者:跟张哥学编程,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:Windows Server 2012 GUI与Core的切换

      下一篇:CentOS 查询指定用户组下的所有用户

      相关文章

      2024-11-15 06:46:25

      app自动化测试——XPATH高级用法

      app自动化测试——XPATH高级用法

      2024-11-15 06:46:25
      android , 节点
      2024-11-15 06:46:25

      app自动化测试——capability 配置参数解析

      app自动化测试——capability 配置参数解析

      2024-11-15 06:46:25
      android , Android , true , 参数 , 配置
      2024-10-17 08:20:58

      二叉树---堆的现实

      二叉树---堆的现实

      2024-10-17 08:20:58
      android , 数据结构
      2024-09-25 10:15:15

      Android ViewDragHelper:控制子View能否拖曳及水平方向的拖曳边界(2)

       Android ViewDragHelper:控制子View能否拖曳及水平方向的拖曳边界(2)

      2024-09-25 10:15:15
      android
      2024-09-25 10:15:15

      初学Android,数据存储之使用SQLite数据库(四十六)

      SQLiteOpenHelper是Android提供的一个管理sqlite数据库的一个工具类

      2024-09-25 10:15:15
      android , 存储 , 数据库
      2024-09-25 10:13:57

      Windows下,Ant自动化编译Android项目具体步骤和方法

      Windows下,Ant自动化编译Android项目具体步骤和方法

      2024-09-25 10:13:57
      android
      2024-09-25 10:13:46

      Android DialogFragment(2)

       Android DialogFragment(2)

      2024-09-25 10:13:46
      android
      2024-09-25 10:13:46

      Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二)

      Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二)

      2024-09-25 10:13:46
      android , Job , 线程
      2024-09-25 10:13:34

      【Android入门到项目实战-- 5.3】—— 广播实战使用(强制下线到登录界面)

      【Android入门到项目实战-- 5.3】—— 广播实战使用(强制下线到登录界面)

      2024-09-25 10:13:34
      android , java , 开发语言
      2024-09-25 10:13:34

      Flutter NavigationBar 优雅的实现底部导航栏菜单

      Flutter NavigationBar 优雅的实现底部导航栏菜单

      2024-09-25 10:13:34
      android , flutter
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5238684

      查看更多

      最新文章

      Android ViewDragHelper:控制子View能否拖曳及水平方向的拖曳边界(2)

      2024-09-25 10:15:15

      Windows下,Ant自动化编译Android项目具体步骤和方法

      2024-09-25 10:13:57

      Android DialogFragment(2)

      2024-09-25 10:13:46

      Flutter NavigationBar 优雅的实现底部导航栏菜单

      2024-09-25 10:13:34

      Android自定制Toast显示外观

      2024-09-24 06:30:46

      初学Android,使用Drawable资源之使用StateListDrawable资源(十三)

      2024-08-06 09:37:28

      查看更多

      热门文章

      JAVA基础加强笔记

      2022-11-14 02:56:39

      Android ScrollView嵌套GridView导致GridView只显示一行item

      2023-04-17 10:54:11

      Android创建快捷方式图标

      2023-04-18 14:15:50

      Eclipse设置Android Logcat输出字体大小

      2023-04-21 03:15:03

      Windows下,Ant自动化编译Android项目具体步骤和方法

      2024-09-25 10:13:57

      Android Drawable 转化成 Bitmap

      2023-04-18 14:15:57

      查看更多

      热门标签

      linux java python javascript 数组 前端 docker Linux vue 函数 shell git 节点 容器 示例
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      JAVA基础加强笔记

      Android ScrollView嵌套GridView导致GridView只显示一行item

      Android Accelerometer Sensor

      解决Appium连接报错Could not find ‘apksigner.jar‘

      Eclipse设置Android Logcat输出字体大小

      js:运行设备环境类型判断

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号