效果:如下图。
注意的地方,文字的绘制是从左下角开始的。
代码如下:
public class AgtronCircle extends View {
private static final String TAG = "AgtronCircle";
private Paint mPaint;
//基础颜色
private static String[] colorStrings = {"#A59B7F","#B49279","#876E58","#7B6550","#68594A"
,"#635447","#685B4C","#3F4038","#3A3E35","#151F1B"};
private int mRadius;
private int mAgtron;
private static final String sLight = "Light";
private static final String sAgtron = "(Agtron)";
private Canvas mCanvas;
private Context mContext;
//FIXME 左右不能居中不知道为什么
private float eyeOffestLeft = 3f; //目测偏移。。。
private float eyeOffsetBottom = 1f; //目测偏移。。。
public AgtronCircle(Context context) {
this(context,null);
}
public AgtronCircle(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
public AgtronCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
initPaint();
}
private void initPaint(){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mAgtron = 60;
}
@VisibleForTesting
public static String AgtronToColor(int Agtron){
if (Agtron > 80){
return colorStrings[0];
}else if (Agtron > 70){
return colorStrings[1];
}else if (Agtron >55){
return colorStrings[2];
}else if (Agtron > 25){
return colorStrings[(8 - (Agtron - 25)/5)];
}else
return colorStrings[9];
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
if (modeWidth == MeasureSpec.EXACTLY){
mRadius = sizeWidth/2;
}else {
mRadius = (int)getContext().getResources().getDimension(R.dimen.padding_120);
}
setMeasuredDimension(mRadius*2,mRadius*2);
}
@Override
protected void onDraw(Canvas canvas) {
drawCircle(canvas);
drawText(mAgtron,canvas);
}
private void drawCircle(Canvas canvas){
mPaint.reset();
mPaint.setColor(Color.parseColor(AgtronToColor(mAgtron)));
int padding = getPaddingTop();
canvas.drawCircle(padding + mRadius,padding + mRadius ,mRadius, mPaint);
}
private void drawText(int Agtron,Canvas canvas){
mPaint.reset();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setFakeBoldText(true);
float numTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,35,mContext.getResources().getDisplayMetrics());
float LightTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,20,mContext.getResources().getDisplayMetrics());
float AgtronTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,14,mContext.getResources().getDisplayMetrics());
mPaint.setTextSize(numTextSize);
String AgtronString = String.valueOf(Agtron);
mPaint.measureText(AgtronString);
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float numAreaHeight = Math.abs((fontMetrics.bottom - fontMetrics.top));//这个高度是上下高度,比文字高度高
Rect boundsNum = new Rect(); //这个矩形是文字包裹矩形
mPaint.getTextBounds(AgtronString,0,AgtronString.length(),boundsNum);
canvas.drawText(AgtronString,getWidth()/2 - boundsNum.width()/2 -boundsNum.left - eyeOffestLeft
,getHeight()/2 + boundsNum.height()/2 + eyeOffsetBottom,mPaint);
mPaint.setTextSize(LightTextSize);
Rect lightBounds = new Rect();
mPaint.getTextBounds(sLight,0,sLight.length(),lightBounds);
canvas.drawText(sLight,getWidth()/2 - lightBounds.width()/2 - lightBounds.left - eyeOffestLeft,
getHeight()/2 - numAreaHeight/2 + eyeOffsetBottom ,mPaint);
float marginTop = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,8,mContext.getResources().getDisplayMetrics());
mPaint.setFakeBoldText(false);
mPaint.setTextSize(AgtronTextSize);
Rect agtronBounds = new Rect();
mPaint.getTextBounds(sAgtron,0,sAgtron.length() ,agtronBounds);
canvas.drawText(sAgtron,getWidth()/2 - agtronBounds.width()/2 - agtronBounds.left - eyeOffestLeft,
getHeight()/2 + numAreaHeight/2 + marginTop + eyeOffsetBottom,mPaint);
}
public void setColor(int Agtron){
if (Agtron >= 100)
Agtron = 99;
if (Agtron <= 0)
Agtron = 0;
mAgtron = Agtron;
mPaint.reset();
mPaint.setAntiAlias(true);
String color = AgtronToColor(Agtron);
mPaint.setColor(Color.parseColor(color));
invalidate();
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
setColor(savedState.currentAgtron);
}
@Nullable
@Override
protected Parcelable onSaveInstanceState() {
Parcelable parcelable = super.onSaveInstanceState();
SavedState savedState = new SavedState(parcelable);
savedState.currentAgtron = mAgtron;
return savedState;
}
private static class SavedState extends BaseSavedState{
int currentAgtron;
public SavedState(Parcel source) {
super(source);
currentAgtron = source.readInt();
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(currentAgtron);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>(){
@Override
public SavedState createFromParcel(Parcel source) {
return new SavedState(source);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
在Xml文件中引用即可。