【Android实战决】使用帧动画实现自定义loading加载布局


在项目开发过程中,我们总是需要自定义一些和项目风格类似的loading页面,这时候我们可以考虑使用帧动画来完成这一功能

假如我们要实现如下图所示的帧动画加载效果:

【Android实战决】使用帧动画实现自定义loading加载布局_第1张图片

我们可以选取三张帧图片:

具体在帧动画中怎么使用?

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();


还是挺简单的!希望对大家有帮助!


你可能感兴趣的:(android,animation,帧动画,自定义布局)