FruitLoadView 一個自定義view可用來做加載view

閒暇時自己做得一個自定義view,後續如果還有時間的話再去增強功能。

Github地址:https://github.com/X-FAN/FruitLoadView 歡迎star

效果圖
博客上的圖片文件不能太大,github效果圖要清晰些,大家將就下
這裏寫圖片描述

2016.8.5:
新增fruitDrawableArray屬性,可以在跳動中變換
這裏寫圖片描述

源碼還是比較簡單的

public class FruitLoadView extends View {
    private final String TAG = "Fruit";
    private int mWidth;
    private int mHeight;
    private int mOvalW;
    private int mOvalH;
    private int mStartHeight;
    private int mFruitHeight;
    private int mFruitWidth;
    private int mIndex = 1;
    private int mLength;
    private boolean mIsDraw = false;
    private boolean mIsMutliMode = false;
    private boolean mIsHasChanged = false;//是否已經變換過在達到最高前
    private float mMinScale;
    private float mAnimatedValue = 1.0f;
    private List<Drawable> mFruitDrawables;

    private Drawable mFruitDrawable;
    private ValueAnimator mScaleLargerAnimator;
    private Paint mPaint;
    private RectF mOvalRectF;


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


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

    public FruitLoadView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }


    private void init(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FruitLoadView);
        handleMultiDrawable(a);
        if (!mIsMutliMode) {
            mFruitDrawable = a.getDrawable(R.styleable.FruitLoadView_fruitDrawable);
            if (mFruitDrawable == null) {
                throw new NullPointerException("fruit drawable is null");
            }
        }
        int shadowColor = a.getColor(R.styleable.FruitLoadView_shadowColor, 0xFFE6E6E6);
        int animatorDuration = a.getInt(R.styleable.FruitLoadView_animatorDuration, 1000);
        int maxHeight = a.getDimensionPixelSize(R.styleable.FruitLoadView_maxHeight, 100);
        int fruitHeight = a.getDimensionPixelSize(R.styleable.FruitLoadView_fruitHeight, -1);
        int fruitWidth = a.getDimensionPixelSize(R.styleable.FruitLoadView_fruitWidth, -1);
        if (fruitHeight > 0) {
            mFruitHeight = fruitHeight;
        } else {
            mFruitHeight = mFruitDrawable.getIntrinsicHeight();
        }
        if (fruitWidth > 0) {
            mFruitWidth = fruitWidth;
        } else {
            mFruitWidth = mFruitDrawable.getIntrinsicWidth();
        }
        mOvalW = mFruitWidth / 2;
        mOvalH = (int) (mFruitHeight * 0.5) / 2;
        mStartHeight = mFruitHeight + maxHeight;
        mMinScale = (float) mFruitHeight / (float) mStartHeight;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(shadowColor);
        mOvalRectF = new RectF();
        initAnimator(animatorDuration);
        a.recycle();
    }

    /**
     * 處理多個drawable的情況
     *
     * @param a
     */
    private void handleMultiDrawable(TypedArray a) {
        int resId = a.getResourceId(R.styleable.FruitLoadView_fruitDrawableArray, -1);
        if (resId != -1) {
            Resources resources = getResources();
            TypedArray typedArray = resources.obtainTypedArray(resId);
            mFruitDrawables = new ArrayList<>();
            for (int i = 0; i < typedArray.length(); i++) {
                Drawable drawable = typedArray.getDrawable(i);
                mFruitDrawables.add(drawable);
            }
            if (!mFruitDrawables.isEmpty()) {
                mIsMutliMode = true;
                mFruitDrawable = mFruitDrawables.get(0);
                mLength = mFruitDrawables.size();
            }
            typedArray.recycle();
        }
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mIsDraw) {
            canvas.translate(mWidth / 2, mHeight / 2);// 將畫布座標原點移動到中心位置
            canvas.save();
            canvas.drawOval(mOvalRectF, mPaint);
            mFruitDrawable.setBounds(-mOvalW, (int) (-mStartHeight * mAnimatedValue), mOvalW, (int) (-(mStartHeight * mAnimatedValue - mFruitHeight)));
            mFruitDrawable.draw(canvas);
            canvas.restore();
        }

    }


    private void initAnimator(long duration) {
        mScaleLargerAnimator = ValueAnimator.ofFloat(1.0f, mMinScale, 1.0f).setDuration(duration);
        mScaleLargerAnimator.setInterpolator(new DecelerateInterpolator());
        mScaleLargerAnimator.setRepeatCount(ValueAnimator.INFINITE);
        mScaleLargerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimatedValue = (float) animation.getAnimatedValue();
                if (mAnimatedValue > 0.9f) {//認爲達到最高點
                    mIsHasChanged = false;
                }
                mOvalRectF.set(-mOvalW * mAnimatedValue, -mOvalH * mAnimatedValue, mOvalW * mAnimatedValue, mOvalH * mAnimatedValue);
                changeDrawable();
                invalidate();
            }
        });
        mScaleLargerAnimator.start();
    }

    /**
     * 變更需要繪製的drawable
     */
    private void changeDrawable() {
        //差值小於0.05f即認爲在最低點
        if (mIsMutliMode && !mIsHasChanged && (mAnimatedValue - mMinScale) < 0.05f) {
            mFruitDrawable = mFruitDrawables.get(mIndex);
            if (mIndex < mLength - 1) {
                mIndex++;
            } else {
                mIndex = 0;
            }
            mIsHasChanged = true;
        }
    }


    /**
     * 是否正在展示
     *
     * @return
     */
    public boolean isShowing() {
        return mIsDraw;
    }

    /**
     * 展示
     */
    public void showLoading() {
        mIsDraw = true;
        mScaleLargerAnimator.start();
    }

    /**
     * 消失
     */
    public void hideLoading() {
        mIsDraw = false;
        mScaleLargerAnimator.cancel();
        mScaleLargerAnimator.end();
    }
}
發佈了64 篇原創文章 · 獲贊 120 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章