-
android:text=“runFrame”
-
android:onClick=“runFrame”/>
-
</LinearLayout>
<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 ?
-
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();
-
}
-
}
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 ?
-
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();
-
}
-
}
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 ?
-
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();
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 ?
-
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); //将动画资源文件设置为ImageView的背景
-
AnimationDrawable anim = (AnimationDrawable) image.getBackground(); //获取ImageView背景,此时已被编译成AnimationDrawable
-
anim.start(); //开始动画
-
}
-
public void stopFrame(View view) {
-
AnimationDrawable anim = (AnimationDrawable) image.getBackground();
-
if (anim.isRunning()) { //如果正在运行,就停止
-
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学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!