//完整代码
package com.thb.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by thbpc on 2016/1/21 0021.
*/
public class ProgressView extends View {
private int mWidth, mHeight;
private float maxCount;
private float mProgress;
private Paint mPaint;
private float mSection;
private int mBackgroundColor;
/**
* 分段颜色
*/
private static final int[] SECTION_COLORS = new int[3];
public ProgressView(Context context) {
this(context, null);
}
public ProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);
try {
mProgress = mTypedArray.getFloat(R.styleable.ProgressView_progress, 0);
maxCount = mTypedArray.getFloat(R.styleable.ProgressView_max, 100);
mSection = mTypedArray.getFloat(R.styleable.ProgressView_section, 0);
mBackgroundColor = mTypedArray.getColor(R.styleable.ProgressView_backgroundColor, Color.TRANSPARENT);
SECTION_COLORS[0] = mTypedArray.getColor(R.styleable.ProgressView_startColor, Color.RED);
SECTION_COLORS[1] = mTypedArray.getColor(R.styleable.ProgressView_centerColor, Color.GREEN);
SECTION_COLORS[2] = mTypedArray.getColor(R.styleable.ProgressView_endColor, Color.BLUE);
} finally {
mTypedArray.recycle();
}
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
/**
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.reset();
mPaint.setAntiAlias(true);// 设置画笔的锯齿效果
mPaint.setStyle(Paint.Style.FILL);//设置填满
float mCircleRadius = mHeight / 2;
float mRatio = mProgress / maxCount;
mPaint.setColor(mBackgroundColor);
RectF mCircleRectF = new RectF(0, 0, 0, 0);
//画背景矩形
RectF backgroudRect = new RectF(0, 0, mWidth - mCircleRadius, mHeight);
canvas.drawRect(backgroudRect, mPaint);
//画背景半圆
mCircleRectF.left = mWidth - mCircleRadius * 2;
mCircleRectF.top = 0;
mCircleRectF.right = mWidth;
mCircleRectF.bottom = mHeight;
canvas.drawArc(mCircleRectF, -90, 180, false, mPaint);
if (mProgress != 0) {
LinearGradient shader = new LinearGradient(mWidth * mRatio * mSection, mHeight / 2,
mWidth * mRatio, mHeight / 2, SECTION_COLORS, null, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
RectF progressOval = new RectF(0, 0, mWidth * mRatio < mWidth - mCircleRadius ?
mWidth * mRatio : mWidth - mCircleRadius, mHeight);
canvas.drawRect(progressOval, mPaint);
if (mRatio * mWidth > mWidth - mCircleRadius) {//当前进度大于宽度减半径
mCircleRectF.left = mWidth - mCircleRadius * 2;
mCircleRectF.top = 0;
mCircleRectF.right = mRatio * mWidth;
mCircleRectF.bottom = mHeight;
canvas.drawArc(mCircleRectF, -90, 180, false, mPaint);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == View.MeasureSpec.EXACTLY || widthSpecMode == View.MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}
if (heightSpecMode == View.MeasureSpec.AT_MOST || heightSpecMode == View.MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(15);
} else {
mHeight = heightSpecSize;
}
setMeasuredDimension(mWidth, mHeight);
}
private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}
/***
* 设置最大的进度值
*
* @param maxCount
*/
public void setMax(float maxCount) {
this.maxCount = maxCount;
}
/***
* 设置当前的进度值
*
* @param currentCount
*/
public void setProgress(float currentCount) {
this.mProgress = currentCount > maxCount ? maxCount : currentCount;
invalidate();
}
public float getProgress() {
return mProgress;
}
public float getMax() {
return maxCount;
}
}
//attr文件
<declare-styleable name="ProgressView">
<attr name="startColor" format="color" />
<attr name="endColor" format="color" />
<attr name="centerColor" format="color" />
<attr name="backgroundColor" format="color" />
<attr name="max" format="float" />
<attr name="progress" format="float" />
<attr name="section" format="float" />
</declare-styleable>
//xml引用
<com.thb.view.ProgressView
android:id="@+id/mview"
android:layout_width="match_parent"
android:layout_height="20dp"
app:backgroundColor="#e4e4e4"
app:centerColor="@color/CenterColor"
app:endColor="@color/endColor"
app:max="500"
app:progress="0"
app:section="0.1"
app:startColor="@color/startColor" />
//效果图