使用LevelListDrawable实现一个动画控件

在华为的时候做过一个麦克风的控件,用户音量发生变化的时候绘制不同的drawable,其中就用到了LevelListDrawable。使用这个知识我写了一个动画控件,可以在加载新页面的时候使用。

基础知识可以参考这一篇文章:《同一个ImageView显示不同的图片(LevelDrawable)》

首先是自定义属性:

    <declare-styleable name="LoadingView">
        <attr name="src" format="reference"/>
        <attr name="duration" format="integer"/>
        <attr name="num" format="integer"/>
    </declare-styleable>

 控件类:

/**
 * 加载动画
 */
public class LoadingView extends View
{
    public static final int DEFAULT_DURATION = 100;
    public static final int DEFAULT_NUM = 1;
    private Drawable mDrawable;
    private int mCounter = 0;
    private boolean mPaused = false;
    private long mDuration;
    private int mNum;

    public LoadingView(Context context)
    {
        this(context, null);
    }

    public LoadingView(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public LoadingView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LoadingView);
        mDrawable = array.getDrawable(array.getIndex(R.styleable.LoadingView_src));
        mDuration = array.getInt(array.getIndex(R.styleable.LoadingView_duration), DEFAULT_DURATION);
        mNum = array.getInt(array.getIndex(R.styleable.LoadingView_num),DEFAULT_NUM);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        float ratio = Math.min(getMeasuredWidth() * 1.0f / mDrawable.getIntrinsicWidth(), getMeasuredHeight() * 1.0f / mDrawable.getIntrinsicHeight());
        mDrawable.setBounds(0, 0, (int) (mDrawable.getIntrinsicWidth() * ratio), (int) (mDrawable.getIntrinsicHeight() * ratio));
        canvas.save();
        //移动canvas的原点
        canvas.translate((getMeasuredWidth() - mDrawable.getIntrinsicWidth() * ratio) / 2, (getMeasuredHeight() - mDrawable.getIntrinsicHeight() * ratio) / 2);
        mDrawable.draw(canvas);
        canvas.restore();
        postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                if (!mPaused)
                {
                    mDrawable.setLevel(mCounter % mNum);
                    mCounter = mCounter == mNum ? 0 : mCounter + 1;
                    invalidate();
                }
            }
        }, mDuration);
    }

    @Override
    protected void onDetachedFromWindow()
    {
        mPaused = true;
        super.onDetachedFromWindow();
    }
}

 使用:

  1.创建drawable文件loading_ali.xml

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/loading0"
        android:maxLevel="0"/>
    <item
        android:drawable="@drawable/loading1"
        android:maxLevel="1"/>
    <item
        android:drawable="@drawable/loading2"
        android:maxLevel="2"/>
    <item
        android:drawable="@drawable/loading3"
        android:maxLevel="3"/>
    <item
        android:drawable="@drawable/loading4"
        android:maxLevel="4"/>
</level-list>

在布局文件中使用:

    <com.hsji.testptr.widget.LoadingView
            android:layout_width="120dp"
            android:layout_height="80dp"
            app:duration="130"
            app:num="5"
            app:src="@drawable/loading_ali"/>
原文地址:https://www.cnblogs.com/hsji/p/5131272.html