我们都知道在Android中,常见的动画模式有两种:一种是帧动画(Frame Animation),一种是补间动画(Tween Animation)。帧动画是提供了一种逐帧播放图片的动画方式,播放事先做好的图像,与gif图片原理类似,就像是在放电影一样。补间动画可以实现View组件的移动、放大、缩小以及渐变等效果。
今天我们主要来模仿一下美团中加载数据时小人奔跑动画的对话框效果,取个有趣的名字就是Running Man,奔跑吧,兄弟!话不多少,先上效果图,让各位大侠看看是不是你想要实现的效果,然后再决定是否往下阅读,因为做为程序员我们的时间都很宝贵,毕竟还没有女朋友呢?
下面讲讲实现的原理,首先我们在项目的res目录下新建一下anim文件夹,然后新建一个xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/app_loading0"
android:duration="150"/>
<item
android:drawable="@drawable/app_loading1"
android:duration="150"/>
</animation-list>
animation-list 是动画列表,中间放很多的item 也就是组成帧动画的图片,
android:drawable[drawable]//加载Drawable对象
android:duration[long]//每一帧动画的持续时间(单位ms) android:oneshot[boolean]//动画是否只运行一次,true运行一次,false重复运行
写好之后我们来看自定义一个对话框,来实现打开对话框时,自动加载奔跑的动画。见代码:
/**
* @Description:自定义对话框
* @author http://blog.csdn.net/finddreams
*/
public class CustomProgressDialog extends ProgressDialog {
private AnimationDrawable mAnimation;
private Context mContext;
private ImageView mImageView;
private String mLoadingTip;
private TextView mLoadingTv;
private int count = 0;
private String oldLoadingTip;
private int mResid;
public CustomProgressDialog(Context context, String content, int id) {
super(context);
this.mContext = context;
this.mLoadingTip = content;
this.mResid = id;
setCanceledOnTouchOutside(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initData();
}
private void initData() {
mImageView.setBackgroundResource(mResid);
// 通过ImageView对象拿到背景显示的AnimationDrawable
mAnimation = (AnimationDrawable) mImageView.getBackground();
// 为了防止在onCreate方法中只显示第一帧的解决方案之一
mImageView.post(new Runnable() {
@Override
public void run() {
mAnimation.start();
}
});
mLoadingTv.setText(mLoadingTip);
}
public void setContent(String str) {
mLoadingTv.setText(str);
}
private void initView() {
setContentView(R.layout.progress_dialog);
mLoadingTv = (TextView) findViewById(R.id.loadingTv);
mImageView = (ImageView) findViewById(R.id.loadingIv);
}
}
可以看到在代码中,我们使用到一个imageview.post(Runnable r)方法,因为帧动画需要不断的重画,所以必须在线程中运行,否则只能看到第一帧的效果,这和我们做游戏的原理是一样的,一个人物的走动,是有线程在控制图片的不断重画。
当然还有另外一个方法也能实现:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
mAnimation.start();
super.onWindowFocusChanged(hasFocus);
}
最后就是在Activity中调用了
CustomProgressDialog dialog =new CustomProgressDialog(this, "正在加载中",R.anim.frame);
dialog.show();
对于CustomProgressDialog这个自定义对话框类是封装的比较好的,调用起来十分方便,你可以快速的替换成你想要的效果,只需更改图片就可以了。