1. 程式人生 > >自定義圓形progressbar(包含進度動畫效果)

自定義圓形progressbar(包含進度動畫效果)

效果圖敬上:)

這裡寫圖片描述

attrs檔案:
< resources>
< declare-styleable name=”CircleProgressBarStyle”>
< attr name=”circleColor” format=”color”/>
< attr name=”circleProgressColor” format=”color”/>
< attr name=”progressWidth” format=”float”/>
< attr name=”progress” format=”integer”/>
< attr name=”max” format=”integer”/>
< attr name=”progressPadding” format=”integer”/>
< attr name=”animation” format=”boolean”/>
< attr name=”style”>
< enum name=”STROKE” value=”0”/>
< enum name=”FILL” value=”1”/>
< /attr>
< /declare-styleable>
< /resources>

xml檔案:記著加 xmlns:progress=”http://schemas.android.com/apk/res-auto”

 < com.test.ffmpeg.CircleProgressBar
        android:id="@+id/CircleProgressBar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        progress:circleColor="@color/white"
        progress:circleProgressColor="@color/colorAccent"
        progress:progressWidth="10"
        progress:progressPadding="15"
        progress:progress="50"
        progress:max="100"
        progress:animation="true"
        progress:style="FILL"/>

CircleProgressBar:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * 自定義圓形progressbar
 */

public class CircleProgressBar extends View {
    /**
     * 畫筆
     */
    private Paint mPaint;
    /**
     * 實心圓顏色
     */
    private int CircleColor;
    /**
     * 圓環顏色
     */
    private int CircleProgressColor;
    /**
     * 圓環寬度
     */
    private float CircleProgressWidth;
    /**
     * 實心圓與環間的距離
     */
    private int ProgressPadding;
    /**
     * 最大進度
     */
    private int ProgressMax;
    /**
     * 進度的風格,是否繪畫內部實心圓
     */
    private int style;
    /**
     * 當前進度
     */
    private int progress;
    /**
     * 顯示時是否需要動畫效果
     */
    private boolean animation;
    /**
     * 進度動畫更新次數
     */
    private int speed = 100;//這裡修改的話每隔10ms處也應修該,個人感覺這個值正好!

 private double progress_=0;//臨時儲存double型別格式的進度
private int temporaryProgress=0;//臨時存放記錄的progress
private double temporary=0;
private boolean isFirst=true;//是否是第一次繪製
private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if(speed>=0) {
            speed--;
            progress_ = progress_ + temporary;
            if(progress_>=temporaryProgress){
                progress=temporaryProgress;
            }else {
                progress= (int) progress_;
            }
            setProgress(progress);
            mHandler.sendEmptyMessageDelayed(1, 10);//每隔10ms執行一次
        }else {
            mHandler.removeMessages(1);
        }

    }
};


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

public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);//!!!
}

public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mPaint = new Paint();
    //獲取自定義屬性值
    TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBarStyle);

    CircleColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleColor, Color.WHITE);
    CircleProgressColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleProgressColor, Color.BLUE);
    CircleProgressWidth = mTypedArray.getFloat(R.styleable.CircleProgressBarStyle_progressWidth, 5);
    ProgressMax = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_max, 100);
    style = mTypedArray.getInt(R.styleable.CircleProgressBarStyle_style, 1);
    progress = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progress, 60);
    ProgressPadding = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progressPadding, 0);
    animation = mTypedArray.getBoolean(R.styleable.CircleProgressBarStyle_animation, false);

    mTypedArray.recycle();


}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //開始繪製 內部實心圓
    int circle_x = getWidth() / 2;//獲取圓心座標
    int radius = (int) (circle_x - CircleProgressWidth - ProgressPadding);
    int prgress_radius = (int) (circle_x - CircleProgressWidth);
    if (style == 1) {//判斷是否繪畫內部實心圓
        mPaint.setColor(CircleColor);//畫筆顏色
        mPaint.setStyle(Paint.Style.FILL);//實心
        mPaint.setAntiAlias(true);//消除鋸齒
        canvas.drawCircle(circle_x, circle_x, radius, mPaint);
    }
    //progressbar進度條(扇形環)
    RectF rectF = new RectF(circle_x - prgress_radius, circle_x - prgress_radius,
            circle_x + prgress_radius, circle_x + prgress_radius);
    mPaint.setColor(CircleProgressColor);
    mPaint.setStyle(Paint.Style.STROKE);//空心
    mPaint.setStrokeWidth(CircleProgressWidth);//圓環寬度
    mPaint.setAntiAlias(true);//消除鋸齒
    if (animation && isFirst) {
        isFirst=false;
        temporary=(double) progress/speed;//設定每次progress增量值
        Log.e("增量",""+temporary);
        temporaryProgress=progress;//記錄
        progress=0;//歸0
        mHandler.sendEmptyMessage(1);
    }
    canvas.drawArc(rectF, -90, 360 * progress / ProgressMax, false, mPaint);

}

public int getCircleColor() {
    return CircleColor;
}

public void setCircleColor(int circleColor) {
    CircleColor = circleColor;
}

public int getCircleProgressColor() {
    return CircleProgressColor;
}

public void setCircleProgressColor(int circleProgressColor) {
    CircleProgressColor = circleProgressColor;
}

public float getCircleProgressWidth() {
    return CircleProgressWidth;
}

public void setCircleProgressWidth(float circleProgressWidth) {
    CircleProgressWidth = circleProgressWidth;
}

public int getProgressPadding() {
    return ProgressPadding;
}

public void setProgressPadding(int progressPadding) {
    ProgressPadding = progressPadding;
}

public int getProgressMax() {
    return ProgressMax;
}

public void setProgressMax(int progressMax) {
    if (progressMax > 0)
        ProgressMax = progressMax;
}

public int getStyle() {
    return style;
}

public void setStyle(int style) {
    this.style = style;
}

public synchronized int getProgress() {
    return progress;
}

/**
 * 加個鎖,防止屬性animation和外部同時呼叫該方法異常
 *
 * @param progress
 */
    public synchronized void setProgress(int progress) {
        if (progress > 0)
            this.progress = progress > ProgressMax ? ProgressMax : progress;
        postInvalidate();
     }
  public boolean isAnimation() {
    return animation;
}

public void setAnimation(boolean animation) {
    this.animation = animation;
}
  }