详解Android动画之Frame Animation

  1. android:text=“runFrame”

  2. android:onClick=“runFrame”/>

  3. </LinearLayout>

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

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:orientation=“vertical”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<ImageView

android:id=“@+id/frame_image”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”

android:layout_weight=“1”/>

<Button

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:text=“stopFrame”

android:onClick=“stopFrame”/>

<Button

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:text=“runFrame”

android:onClick=“runFrame”/>

我们定义了一个ImageView作为动画的载体,然后定义了两个按钮,分别是停止和启动动画。

接下来介绍一下如何通过加载动画定义文件来实现动画的效果。我们首先会这样写:

[java] view plain copy print ?

  1. package com.scott.anim;

  2. import android.app.Activity;

  3. import android.graphics.drawable.AnimationDrawable;

  4. import android.graphics.drawable.Drawable;

  5. import android.os.Bundle;

  6. import android.view.View;

  7. import android.widget.ImageView;

  8. public class FrameActivity extends Activity {

  9. private ImageView image;

  10. @Override

  11. protected void onCreate(Bundle savedInstanceState) {

  12. super.onCreate(savedInstanceState);

  13. setContentView(R.layout.frame);

  14. image = (ImageView) findViewById(R.id.frame_image);

  15. image.setBackgroundResource(R.anim.frame);

  16. AnimationDrawable anim = (AnimationDrawable) image.getBackground();

  17. anim.start();

  18. }

  19. }

package com.scott.anim;

import android.app.Activity;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.view.View;

import android.widget.ImageView;

public class FrameActivity extends Activity {

private ImageView image;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.frame);

image = (ImageView) findViewById(R.id.frame_image);

image.setBackgroundResource(R.anim.frame);

AnimationDrawable anim = (AnimationDrawable) image.getBackground();

anim.start();

}

}

看似十分完美,跟官方文档上写的一样,然而当我们运行这个程序时会发现,它只停留在第一帧,并没有出现我们期望的动画,也许你会失望的说一句:“Why?”,然后你把相应的代码放在一个按钮的点击事件中,动画就顺利执行了,再移回到onCreate中,还是没效果,这个时候估计你会气急败坏的吼一句:“What the fuck!”。但是,什么原因呢?如何解决呢?

出现这种现象是因为当我们在onCreate中调用AnimationDrawable的start方法时,窗口Window对象还没有完全初始化,AnimationDrawable不能完全追加到窗口Window对象中,那么该怎么办呢?我们需要把这段代码放在onWindowFocusChanged方法中,当Activity展示给用户时,onWindowFocusChanged方法就会被调用,我们正是在这个时候实现我们的动画效果。当然,onWindowFocusChanged是在onCreate之后被调用的,如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我们需要重写一下代码:

[java] view plain copy print ?

  1. package com.scott.anim;

  2. import android.app.Activity;

  3. import android.graphics.drawable.AnimationDrawable;

  4. import android.graphics.drawable.Drawable;

  5. import android.os.Bundle;

  6. import android.view.View;

  7. import android.widget.ImageView;

  8. public class FrameActivity extends Activity {

  9. private ImageView image;

  10. @Override

  11. protected void onCreate(Bundle savedInstanceState) {

  12. super.onCreate(savedInstanceState);

  13. setContentView(R.layout.frame);

  14. image = (ImageView) findViewById(R.id.frame_image);

  15. }

  16. @Override

  17. public void onWindowFocusChanged(boolean hasFocus) {

  18. super.onWindowFocusChanged(hasFocus);

  19. image.setBackgroundResource(R.anim.frame);

  20. AnimationDrawable anim = (AnimationDrawable) image.getBackground();

  21. anim.start();

  22. }

  23. }

package com.scott.anim;

import android.app.Activity;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.view.View;

import android.widget.ImageView;

public class FrameActivity extends Activity {

private ImageView image;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.frame);

image = (ImageView) findViewById(R.id.frame_image);

}

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

image.setBackgroundResource(R.anim.frame);

AnimationDrawable anim = (AnimationDrawable) image.getBackground();

anim.start();

}

}

运行一下,动画就可以正常显示了。

如果在有些场合,我们需要用纯代码方式实现一个动画,我们可以这样写:

[java] view plain copy print ?

  1. AnimationDrawable anim = new AnimationDrawable();

  2. for (int i = 1; i <= 4; i++) {

  3. int id = getResources().getIdentifier(“f” + i, “drawable”, getPackageName());

  4. Drawable drawable = getResources().getDrawable(id);

  5. anim.addFrame(drawable, 300);

  6. }

  7. anim.setOneShot(false);

  8. image.setBackgroundDrawable(anim);

  9. anim.start();

AnimationDrawable anim = new AnimationDrawable();

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

int id = getResources().getIdentifier(“f” + i, “drawable”, getPackageName());

Drawable drawable = getResources().getDrawable(id);

anim.addFrame(drawable, 300);

}

anim.setOneShot(false);

image.setBackgroundDrawable(anim);

anim.start();

完整的FrameActivity.java代码如下:

[java] view plain copy print ?

  1. package com.scott.anim;

  2. import android.app.Activity;

  3. import android.graphics.drawable.AnimationDrawable;

  4. import android.graphics.drawable.Drawable;

  5. import android.os.Bundle;

  6. import android.view.View;

  7. import android.widget.ImageView;

  8. public class FrameActivity extends Activity {

  9. private ImageView image;

  10. @Override

  11. protected void onCreate(Bundle savedInstanceState) {

  12. super.onCreate(savedInstanceState);

  13. setContentView(R.layout.frame);

  14. image = (ImageView) findViewById(R.id.frame_image);

  15. }

  16. @Override

  17. public void onWindowFocusChanged(boolean hasFocus) {

  18. super.onWindowFocusChanged(hasFocus);

  19. image.setBackgroundResource(R.anim.frame);  //将动画资源文件设置为ImageView的背景

  20. AnimationDrawable anim = (AnimationDrawable) image.getBackground(); //获取ImageView背景,此时已被编译成AnimationDrawable

  21. anim.start();   //开始动画

  22. }

  23. public void stopFrame(View view) {

  24. AnimationDrawable anim = (AnimationDrawable) image.getBackground();

  25. if (anim.isRunning()) { //如果正在运行,就停止

  26. anim.stop();

题外话

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-2If8blNe-1715395251746)]

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展~
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值