在项目开发过程中,我们总是需要自定义一些和项目风格类似的loading页面,这时候我们可以考虑使用帧动画来完成这一功能
假如我们要实现如下图所示的帧动画加载效果:
具体在帧动画中怎么使用?
An AnimationDrawable defined in XML consists of a single <animation-list>
element, and a series of nested<item>
tags. Each item defines a frame of the animation. See the example below.
我们的res/drawable/loading_animation的代码如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/selected" android:oneshot="false"> <item android:drawable="@drawable/loading_big1" android:duration="500" /> <item android:drawable="@drawable/loading_big2" android:duration="500" /> <item android:drawable="@drawable/loading_big3" android:duration="500" /> </animation-list>这里就不过多解释,然后接下来看我们自定义的DurianLoading
public class DurianLoading extends RelativeLayout { private AnimationDrawable frameAnimation;//创建帧动画的对象 private ImageView loadingImg;//加载图片 private TextView textView;//加载文字 private Context mContext; public DurianLoading(Context context) { super(context); initView(context); } public DurianLoading(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } //停止动画 private void stopLoadingAnimation() { setVisibility(View.GONE); if (frameAnimation != null) { if (frameAnimation.isRunning()) { frameAnimation.stop(); } } } /** * 布局中的图片和文字是通过动态加载的方式处理的 * 这里面添加了一张图片和一个textview */ private void initView(Context context) { mContext = context; LayoutParams imgLp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); imgLp.addRule(RelativeLayout.CENTER_HORIZONTAL);//设置图片水平居中 loadingImg = new ImageView(context); loadingImg.setId(Integer.parseInt("1"));//给loadingImg设置一个坐标,可以作为下面空间的参考位置 loadingImg.setLayoutParams(imgLp); addView(loadingImg); LayoutParams textLp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); textLp.addRule(RelativeLayout.CENTER_IN_PARENT); textLp.addRule(RelativeLayout.BELOW, loadingImg.getId()); textView = new TextView(context); setLoadUi(null); textView.setLayoutParams(textLp); addView(textView); } /** * 设置load文字 */ private void setLoadUi(String loadText) { textView.setTextColor(Color.BLACK); textView.setTextSize(16); if (loadText == null) { showLoadUi(false, 0); } else { showReloadUi(); } } /** * 显示加载动画 * * @param isStopAnim 是否需要停止动画 * @param loadTextStringId 加载文字,如果不自定义加载文字,此值为0 */ public void showLoadUi(boolean isStopAnim, int loadTextStringId) { if (isStopAnim) { stopLoadingAnimation(); } else { setVisibility(View.VISIBLE); if (loadTextStringId != 0) { textView.setText("加载数据中...0.0"); } else { textView.setText("加载数据中..."); } //给图片设置加载动画 loadingImg.setBackgroundResource(R.drawable.loading_animation); frameAnimation = (AnimationDrawable) loadingImg.getBackground(); //启动动画 frameAnimation.start(); } } /** * 显示重新加载页面 * 用途:当加载数据失败的时候显示,我们给当前布局设置点击响应事件,继续load data */ public void showReloadUi() { setVisibility(View.VISIBLE); textView.setText("重新加载"); loadingImg.setBackgroundResource(R.drawable.ic_launcher); } /** * 释放资源 * 在destroy或者destroy view的时候调用 */ public void release() { if (frameAnimation != null && frameAnimation.isRunning()) { frameAnimation.stop(); } frameAnimation = null; if (loadingImg != null) { loadingImg.setImageDrawable(null); } } }然后我们就可以在需要的布局文件中使用
<com.storm.durian.view.DurianLoading android:id="@+id/tel_login_loading_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" />
然后只需:
在需要显示的地方调用showLoadUi(false, 0); 注意:这里加载文字可以自定义
在需要取消的地方调用showLoadUi(true, 0);
在需要重载的地方调用showReloadUi();
在需要释放资源的地方调用release();