效果图
直接上代码,具体看注释
public class MyChart extends View {
final String TAG = "xzc";
public MyChart(Context context) {
this(context,null);
}
public MyChart(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
public MyChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context,attrs,defStyleAttr,0);
}
public MyChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context,attrs,defStyleAttr,defStyleRes);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.module_user_myChart);
mName = array.getString(R.styleable.module_user_myChart_module_user_name);
mCountColor = array.getColor(R.styleable.module_user_myChart_module_user_countColor,Color.BLACK);
mTextColor = array.getColor(R.styleable.module_user_myChart_module_user_textColor,Color.BLACK);
mCurColor = array.getColor(R.styleable.module_user_myChart_module_user_curColor,0xFF19CAAD);
mBackgroundColor = array.getColor(R.styleable.module_user_myChart_module_user_backgroundColor,0x37000000);
array.recycle();
init();
}
private int mMin = 0;
private int mCur = 50;
private int mMax = 100;
private int mPer = 25;
private int mCountColor = Color.BLACK; // 当前进度数量值
private int mTextColor = Color.BLACK; // 文字
private int mCurColor = Color.YELLOW; // 当前进度图案
private int mBackgroundColor = Color.GRAY; // 图表背景
private Paint mPaint;
private Path mBackgroundArcPath;
private Path mCurrArcPath;
private Path mCirclePath;
private int mScaleCount = 8;
private RectF mBackgroundArRect;
private PointF mCenter;
private float mRadius;
private int mTextSize; // 文字字体大小
private int mScaleTextSize; // 刻度字体大小
private int mTextSizeDefault = 10; // 默认文字字体大小 dp
private int mScaleTextSizeDefault = 8; // 默认刻度字体大小 dp
private String mName = "";
private String mCurString = "0";
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mBackgroundArcPath = new Path();
mCurrArcPath = new Path();
mCirclePath = new Path();
mBackgroundArRect = new RectF();
mCenter = new PointF();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w/2+getPaddingLeft();
mCenter.y = h / 4 * 3+getPaddingTop();
mRadius = w/4;
mBackgroundArRect.set(0, h / 4, w, (int) (h / 4 * 3 + h / 2));
mTextSize = (int) (dpToPx(mTextSizeDefault)*w/360f);
mScaleTextSize = (int) (dpToPx(mScaleTextSizeDefault)*w/360f);
Log.i(TAG,"w= "+w+",h = "+h);
}
@Override
protected void onDraw(Canvas canvas) {
mBackgroundArcPath.reset();
mCirclePath.reset();
//mPaint.reset();
mBackgroundArcPath.setFillType(Path.FillType.WINDING);
// 绘制背景
mBackgroundArcPath.addArc(mBackgroundArRect,-135,89);
mBackgroundArcPath.lineTo(mCenter.x,mCenter.y);
//mBackgroundArcPath.close();
mCirclePath.addCircle(mCenter.x, mCenter.y, (float) (mRadius*1.2), Path.Direction.CW);
float tmpX;
float tmpY;
String tempS;
Rect bounds = new Rect(); // 矩形对象
mPaint.setColor(mBackgroundColor);
mPaint.setTextSize(mScaleTextSize);
// 绘制刻度
for(int i=0;i <= mScaleCount;i++){
// 参数为 弧度,
tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.2));
tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.2));
mBackgroundArcPath.lineTo(tmpX,tmpY);
tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i+1))*(mRadius*2.2));
tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i+1))*(mRadius*2.2));
mBackgroundArcPath.lineTo(tmpX,tmpY);
mBackgroundArcPath.lineTo(mCenter.x,mCenter.y);
tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.3));
tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.3));
tempS = (mMin+mPer*i) +"";
mPaint.getTextBounds(tempS, 0, tempS.length(), bounds);
canvas.drawText(tempS,tmpX-bounds.width()/2, tmpY,mPaint);
}
//mBackgroundArcPath.close();
mBackgroundArcPath.op(mCirclePath, Path.Op.DIFFERENCE);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(mBackgroundArcPath, mPaint);
//绘制进度
mBackgroundArcPath.reset();
mBackgroundArcPath.addArc(mBackgroundArRect,-135,90*mCur/(mMax-mMin));
mBackgroundArcPath.lineTo(getWidth()/2,getHeight()/4*3);
mBackgroundArcPath.close();
mBackgroundArcPath.op(mCirclePath, Path.Op.DIFFERENCE);
mPaint.setColor(mCurColor);
canvas.drawPath(mBackgroundArcPath, mPaint);
mPaint.getTextBounds(mName, 0, mName.length(), bounds);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
canvas.drawText(mName,mCenter.x-bounds.width()/2, (float) (mCenter.y-mRadius*0.7),mPaint);
mPaint.setColor(mCountColor);
mCurString = mCur+"";
mPaint.getTextBounds(mCurString, 0, mCurString.length(), bounds);
canvas.drawText(mCurString,mCenter.x-bounds.width()/2, (float) (mCenter.y-mRadius*0.4),mPaint);
}
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
public int pxToDp(int px) {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return dp;
}
public int getMin() {
return mMin;
}
public void setMin(int mMin) {
this.mMin = mMin;
mPer = (mMax-mMin)/mScaleCount;
}
public int getCur() {
return mCur;
}
public void setCur(int mCur) {
this.mCur = mCur;
postInvalidate();
}
public int getMax() {
return mMax;
}
public void setMax(int mMax) {
this.mMax = mMax;
mPer = (mMax-mMin)/mScaleCount;
}
public int getCountColor() {
return mCountColor;
}
public void setCountColor(int mCountColor) {
this.mCountColor = mCountColor;
}
public int getTextColor() {
return mTextColor;
}
public void setTextColor(int mTextColor) {
this.mTextColor = mTextColor;
}
public int getChartColor() {
return mCurColor;
}
public void setChartColor(int mChartColor) {
this.mCurColor = mChartColor;
}
public int getBackgroundColor() {
return mBackgroundColor;
}
public void setBackgroundColor(int mBackgroundColor) {
this.mBackgroundColor = mBackgroundColor;
}
public int getScaleCount() {
return mScaleCount;
}
public void setScaleCount(int mScaleCount) {
this.mScaleCount = mScaleCount;
mPer = (mMax-mMin)/mScaleCount;
}
public int getTextSize() {
return mTextSize;
}
public void setTextSize(int mTextSize) {
this.mTextSize = mTextSize;
}
public int getScaleTextSize() {
return mScaleTextSize;
}
public void setScaleTextSize(int mScaleTextSize) {
this.mScaleTextSize = mScaleTextSize;
}
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
}