package com.example.awesome;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
public class DashboardView extends View {
private int mFirstRangeColor;
private int mSecondRangeColor;
private int mThirdRangeColor;
private int mStartAngle;
private int mSweepAngle;
private int mMin;
private int mMax;
private int mSection;
private int mPortion;
private String mHeaderText;
private int mValue;
private boolean isShowValueText;
private boolean isShowPointerRange;
private float mLineStrokeWidth;
private float mColorStrokeWidth;
private float mColorArcPadding;
private float mLongScaleLength;
private float mShortScaleLength;
private int mScaleColor;
private int mPointerColor;
private int mMinPointerColor;
private int mMaxPointerColor;
private float mScaleTextSize;
private int mHeaderTextColor;
private float mHeaderTextSize;
private int mFirstRange;
private int mSecondRange;
private int mPLRadius;
private int mPSRadius;
private int mRadius;
private int mPadding;
private float mCenterX;
private float mCenterY;
private Paint mPaint;
private RectF mRectFColorArc;
private RectF mRectFLineArc;
private RectF mRectFInnerArc;
private Path mPath;
private Rect mRectText;
private String[] mTexts;
private int mMinValue;
private int mMaxValue;
public DashboardView(Context context) {
this(context, (AttributeSet)null);
}
public DashboardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DashboardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mFirstRangeColor = -65536;
this.mSecondRangeColor = -1024;
this.mThirdRangeColor = -14025425;
this.mStartAngle = 180;
this.mSweepAngle = 180;
this.mMin = 0;
this.mMax = 100;
this.mSection = 10;
this.mPortion = 10;
this.mHeaderText = "Header";
this.mValue = this.mMin;
this.isShowValueText = true;
this.isShowPointerRange = true;
this.mLineStrokeWidth = 2.0F;
this.mColorStrokeWidth = 10.0F;
this.mColorArcPadding = 10.0F;
this.mLongScaleLength = 18.0F;
this.mShortScaleLength = 15.0F;
this.mScaleColor = -1;
this.mPointerColor = -1;
this.mMinPointerColor = -6381922;
this.mMaxPointerColor = -6381922;
this.mScaleTextSize = 30.0F;
this.mHeaderTextColor = -1;
this.mHeaderTextSize = 30.0F;
this.mFirstRange = 40;
this.mSecondRange = 40;
this.mMinValue = this.mValue;
this.mMaxValue = this.mValue;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DashboardView, 0, 0);
this.mFirstRangeColor = a.getColor(R.styleable.DashboardView_dbv_firstColor, this.mFirstRangeColor);
this.mSecondRangeColor = a.getColor(R.styleable.DashboardView_dbv_secondColor, this.mSecondRangeColor);
this.mThirdRangeColor = a.getColor(R.styleable.DashboardView_dbv_thirdColor, this.mThirdRangeColor);
this.mMax = a.getInteger(R.styleable.DashboardView_dbv_max, this.mMax);
this.mMin = a.getInteger(R.styleable.DashboardView_dbv_min, this.mMin);
this.mLineStrokeWidth = a.getDimension(R.styleable.DashboardView_dbv_lineWidth, this.mLineStrokeWidth);
this.mColorStrokeWidth = a.getDimension(R.styleable.DashboardView_dbv_colorWidth, this.mColorStrokeWidth);
this.mColorArcPadding = a.getDimension(R.styleable.DashboardView_dbv_colorPadding, this.mColorArcPadding);
this.mLongScaleLength = a.getDimension(R.styleable.DashboardView_dbv_longScaleLength, this.mLongScaleLength);
this.mShortScaleLength = a.getDimension(R.styleable.DashboardView_dbv_shortScaleLength, this.mShortScaleLength);
this.mStartAngle = a.getInteger(R.styleable.DashboardView_dbv_startAngle, this.mStartAngle);
this.mSweepAngle = a.getInteger(R.styleable.DashboardView_dbv_sweepAngle, this.mSweepAngle);
this.mSection = a.getInteger(R.styleable.DashboardView_dbv_section, this.mSection);
this.mPortion = a.getInteger(R.styleable.DashboardView_dbv_portion, this.mPortion);
this.mValue = a.getInteger(R.styleable.DashboardView_dbv_value, this.mValue);
this.isShowValueText = a.getBoolean(R.styleable.DashboardView_dbv_showValueText, this.isShowValueText);
this.isShowPointerRange = a.getBoolean(R.styleable.DashboardView_dbv_showPointerRange, this.isShowPointerRange);
this.mFirstRange = a.getInteger(R.styleable.DashboardView_dbv_firstRange, this.mFirstRange);
this.mSecondRange = a.getInteger(R.styleable.DashboardView_dbv_secondRange, this.mSecondRange);
this.mScaleColor = a.getColor(R.styleable.DashboardView_dbv_scaleColor, this.mScaleColor);
this.mPointerColor = a.getColor(R.styleable.DashboardView_dbv_pointerColor, this.mPointerColor);
this.mMinPointerColor = a.getColor(R.styleable.DashboardView_dbv_minPointerColor, this.mMinPointerColor);
this.mMaxPointerColor = a.getColor(R.styleable.DashboardView_dbv_maxPointerColor, this.mMaxPointerColor);
this.mScaleTextSize = a.getDimension(R.styleable.DashboardView_dbv_scaleTextSize, this.mScaleTextSize);
this.mHeaderTextColor = a.getColor(R.styleable.DashboardView_dbv_headerTextColor, this.mHeaderTextColor);
this.mHeaderTextSize = a.getDimension(R.styleable.DashboardView_dbv_headerTextSize, this.mHeaderTextSize);
this.mHeaderText = a.getString(R.styleable.DashboardView_dbv_headerText);
a.recycle();
this.init();
}
private void init() {
this.mPSRadius = this.dp2px(10);
this.mPaint = new Paint();
this.mPaint.setAntiAlias(true);
this.mRectFColorArc = new RectF();
this.mRectFLineArc = new RectF();
this.mRectFInnerArc = new RectF();
this.mPath = new Path();
this.mRectText = new Rect();
this.mTexts = new String[this.mSection + 1];
for(int i = 0; i < this.mTexts.length; ++i) {
int n = (this.mMax - this.mMin) / this.mSection;
this.mTexts[i] = String.valueOf(this.mMin + i * n);
}
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.mPadding = Math.max(Math.max(this.getPaddingLeft(), this.getPaddingTop()), Math.max(this.getPaddingRight(), this.getPaddingBottom()));
this.setPadding(this.mPadding, this.mPadding, this.mPadding, this.mPadding);
int width = resolveSize(this.dp2px(200), widthMeasureSpec);
this.mRadius = (int)((float)(width / 2 - this.mPadding) - this.mLineStrokeWidth - this.mColorStrokeWidth - this.mColorArcPadding);
this.mPaint.setTextSize(this.mHeaderTextSize);
if (this.isShowValueText) {
this.mPaint.getTextBounds("0", 0, "0".length(), this.mRectText);
} else {
this.mPaint.getTextBounds("0", 0, 0, this.mRectText);
}
int height = (int)((float)this.mRadius + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding + (float)this.mPSRadius + (float)(this.mRectText.height() * 3));
float[] startPoint = this.getCoordinatePoint(this.mRadius, (float)this.mStartAngle);
float[] endPoint = this.getCoordinatePoint(this.mRadius, (float)(this.mStartAngle + this.mSweepAngle));
int maxHeight = (int)Math.max((float)height, Math.max(startPoint[1] + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding, endPoint[1] + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding));
height = maxHeight + this.getPaddingTop() + this.getPaddingBottom();
this.setMeasuredDimension(width, height);
this.mCenterX = this.mCenterY = (float)this.getMeasuredWidth() / 2.0F;
this.mRectFColorArc.set((float)this.getPaddingLeft() + this.mColorStrokeWidth, (float)this.getPaddingTop() + this.mColorStrokeWidth, (float)(this.getMeasuredWidth() - this.getPaddingRight()) - this.mColorStrokeWidth, (float)(this.getMeasuredWidth() - this.getPaddingBottom()) - this.mColorStrokeWidth);
this.mRectFLineArc.set(this.mRectFColorArc.left + this.mColorArcPadding + this.mLineStrokeWidth, this.mRectFColorArc.top + this.mColorArcPadding + this.mLineStrokeWidth, this.mRectFColorArc.right - this.mColorArcPadding - this.mLineStrokeWidth, this.mRectFColorArc.bottom - this.mColorArcPadding - this.mLineStrokeWidth);
this.mPaint.setTextSize(this.mScaleTextSize);
this.mPaint.getTextBounds("0", 0, "0".length(), this.mRectText);
this.mRectFInnerArc.set(this.mRectFLineArc.left + this.mLongScaleLength + (float)this.mRectText.height() + (float)this.dp2px(3), this.mRectFLineArc.top + this.mLongScaleLength + (float)this.mRectText.height() + (float)this.dp2px(3), this.mRectFLineArc.right - this.mLongScaleLength - (float)this.mRectText.height() - (float)this.dp2px(3), this.mRectFLineArc.bottom - this.mLongScaleLength - (float)this.mRectText.height() - (float)this.dp2px(3));
this.mPLRadius = (int)((float)this.mRadius - (this.mShortScaleLength + (float)this.mRectText.height() + (float)this.dp2px(5)));
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
this.mPaint.setStyle(Paint.Style.STROKE);
this.mPaint.setStrokeWidth(this.mColorStrokeWidth);
this.mPaint.setColor(this.mThirdRangeColor);
canvas.drawArc(this.mRectFColorArc, (float)this.mStartAngle, (float)this.mSweepAngle, false, this.mPaint);
this.mPaint.setColor(this.mSecondRangeColor);
Log.d("YSH",""+mStartAngle+" "+mSweepAngle * (this.mFirstRange + this.mSecondRange) / 100);
canvas.drawArc(this.mRectFColorArc, (float)this.mStartAngle, (float)(this.mSweepAngle * (this.mFirstRange + this.mSecondRange) / 100), false, this.mPaint);
this.mPaint.setColor(this.mFirstRangeColor);
canvas.drawArc(this.mRectFColorArc, (float)this.mStartAngle, (float)(this.mSweepAngle * this.mFirstRange / 100), false, this.mPaint);
this.mPaint.setStyle(Paint.Style.STROKE);
this.mPaint.setStrokeWidth(this.mLineStrokeWidth);
this.mPaint.setColor(this.mScaleColor);
canvas.drawArc(this.mRectFLineArc, (float)this.mStartAngle, (float)this.mSweepAngle, false, this.mPaint);
double cos = Math.cos(Math.toRadians((double)(this.mStartAngle - 180)));
double sin = Math.sin(Math.toRadians((double)(this.mStartAngle - 180)));
float x0 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding) + (double)this.mRadius * (1.0D - cos));
float y0 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding) + (double)this.mRadius * (1.0D - sin));
float x1 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding + (float)this.mRadius) - (double)((float)this.mRadius - this.mLongScaleLength) * cos);
float y1 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding + (float)this.mRadius) - (double)((float)this.mRadius - this.mLongScaleLength) * sin);
canvas.save();
canvas.drawLine(x0, y0, x1, y1, this.mPaint);
float angle = (float)this.mSweepAngle * 1.0F / (float)this.mSection;
for(int i = 0; i < this.mSection; ++i) {
canvas.rotate(angle, this.mCenterX, this.mCenterY);
canvas.drawLine(x0, y0, x1, y1, this.mPaint);
}
canvas.restore();
canvas.save();
this.mPaint.setStrokeWidth(1.0F);
float x2 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding + (float)this.mRadius) - (double)((float)this.mRadius - this.mLongScaleLength / 2.0F) * cos);
float y2 = (float)((double)((float)this.mPadding + this.mLineStrokeWidth + this.mColorStrokeWidth + this.mColorArcPadding + (float)this.mRadius) - (double)((float)this.mRadius - this.mLongScaleLength / 2.0F) * sin);
canvas.drawLine(x0, y0, x2, y2, this.mPaint);
angle = (float)this.mSweepAngle * 1.0F / (float)(this.mSection * this.mPortion);
int i;
for(i = 1; i < this.mSection * mPortion; ++i) {
canvas.rotate(angle, this.mCenterX, mCenterY);
if (i % mPortion != 0) {
canvas.drawLine(x0, y0, x2, y2, mPaint);
}
}
canvas.restore();
this.mPaint.setTextSize(this.mScaleTextSize);
this.mPaint.setTextAlign(Paint.Align.LEFT);
this.mPaint.setStyle(Paint.Style.FILL);
for(i = 0; i < this.mTexts.length; ++i) {
this.mPaint.getTextBounds(this.mTexts[i], 0, this.mTexts[i].length(), this.mRectText);
float θ = (float)((double)(180 * this.mRectText.width() / 2) / (3.141592653589793D * (double)((float)this.mRadius - this.mLongScaleLength - (float)this.mRectText.height())));
this.mPath.reset();
this.mPath.addArc(this.mRectFInnerArc, (float)(this.mStartAngle + i * (this.mSweepAngle / this.mSection)) - θ, (float)this.mSweepAngle);
canvas.drawTextOnPath(this.mTexts[i], this.mPath, 0.0F, 0.0F, this.mPaint);
}
if (!TextUtils.isEmpty(this.mHeaderText)) {
this.mPaint.setColor(this.mHeaderTextColor);
this.mPaint.setTextSize(this.mHeaderTextSize);
this.mPaint.setTextAlign(Paint.Align.CENTER);
this.mPaint.getTextBounds(this.mHeaderText, 0, this.mHeaderText.length(), this.mRectText);
canvas.drawText(this.mHeaderText, this.mCenterX, this.mCenterY / 2.0F + (float)this.mRectText.height(), this.mPaint);
}
this.drawPointer(canvas, this.mValue, this.mPointerColor);
if (this.isShowPointerRange) {
this.drawPointer(canvas, this.mMinValue, this.mMinPointerColor);
this.drawPointer(canvas, this.mMaxValue, this.mMaxPointerColor);
}
this.mPaint.setColor(-16777216);
canvas.drawCircle(this.mCenterX, this.mCenterY, (float)this.dp2px(2), this.mPaint);
if (isShowValueText) {
this.mPaint.setTextSize((float)this.sp2px(16));
this.mPaint.setTextAlign(Paint.Align.CENTER);
this.mPaint.setColor(this.mHeaderTextColor);
String value = String.valueOf(this.mValue);
this.mPaint.getTextBounds(value, 0, value.length(), this.mRectText);
canvas.drawText(value, this.mCenterX, this.mCenterY + (float)this.mPSRadius + (float)(this.mRectText.height() * 2), this.mPaint);
}
}
private void drawPointer(Canvas canvas, int value, int color) {
float θ = (float)(this.mStartAngle + this.mSweepAngle * (value - this.mMin) / (this.mMax - this.mMin));
int d = this.dp2px(5);
this.mPath.reset();
float[] p1 = this.getCoordinatePoint(d, θ - 90.0F);
this.mPath.moveTo(p1[0], p1[1]);
float[] p2 = this.getCoordinatePoint(this.mPLRadius, θ);
this.mPath.lineTo(p2[0], p2[1]);
float[] p3 = this.getCoordinatePoint(d, θ + 90.0F);
this.mPath.lineTo(p3[0], p3[1]);
float[] p4 = this.getCoordinatePoint(this.mPSRadius, θ - 180.0F);
this.mPath.lineTo(p4[0], p4[1]);
this.mPath.close();
this.mPaint.setColor(color);
canvas.drawPath(this.mPath, this.mPaint);
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(1, (float)dp, Resources.getSystem().getDisplayMetrics());
}
private int sp2px(int sp) {
return (int)TypedValue.applyDimension(2, (float)sp, Resources.getSystem().getDisplayMetrics());
}
public float[] getCoordinatePoint(int radius, float angle) {
float[] point = new float[2];
double arcAngle = Math.toRadians((double)angle);
if (angle < 90.0F) {
point[0] = (float)((double)this.mCenterX + Math.cos(arcAngle) * (double)radius);
point[1] = (float)((double)this.mCenterY + Math.sin(arcAngle) * (double)radius);
} else if (angle == 90.0F) {
point[0] = this.mCenterX;
point[1] = this.mCenterY + (float)radius;
} else if (angle > 90.0F && angle < 180.0F) {
arcAngle = 3.141592653589793D * (double)(180.0F - angle) / 180.0D;
point[0] = (float)((double)this.mCenterX - Math.cos(arcAngle) * (double)radius);
point[1] = (float)((double)this.mCenterY + Math.sin(arcAngle) * (double)radius);
} else if (angle == 180.0F) {
point[0] = this.mCenterX - (float)radius;
point[1] = this.mCenterY;
} else if (angle > 180.0F && angle < 270.0F) {
arcAngle = 3.141592653589793D * (double)(angle - 180.0F) / 180.0D;
point[0] = (float)((double)this.mCenterX - Math.cos(arcAngle) * (double)radius);
point[1] = (float)((double)this.mCenterY - Math.sin(arcAngle) * (double)radius);
} else if (angle == 270.0F) {
point[0] = this.mCenterX;
point[1] = this.mCenterY - (float)radius;
} else {
arcAngle = 3.141592653589793D * (double)(360.0F - angle) / 180.0D;
point[0] = (float)((double)this.mCenterX + Math.cos(arcAngle) * (double)radius);
point[1] = (float)((double)this.mCenterY - Math.sin(arcAngle) * (double)radius);
}
return point;
}
public int getValue() {
return this.mValue;
}
public void setValue(int value) {
if (this.mValue != value) {
if (value < this.mMin) {
this.mValue = this.mMin;
} else if (value > this.mMax) {
this.mValue = this.mMax;
} else {
this.mValue = value;
}
if (this.mValue < this.mMinValue) {
this.mMinValue = this.mValue;
}
if (this.mValue > this.mMaxValue) {
this.mMaxValue = this.mValue;
}
this.postInvalidate();
}
}
public void resetValue(int value) {
if (value < this.mMin) {
this.mValue = this.mMin;
} else if (value > this.mMax) {
this.mValue = this.mMax;
} else {
this.mValue = value;
}
this.mMinValue = this.mValue;
this.mMaxValue = this.mValue;
this.postInvalidate();
}
public int getFirstRange() {
return this.mFirstRange;
}
public void setFirstRange(int firstRange) {
this.mFirstRange = firstRange;
this.postInvalidate();
}
public int getSecondRange() {
return this.mSecondRange;
}
public void setSecondRange(int secondRange) {
this.mSecondRange = secondRange;
this.postInvalidate();
}
}
Android仪表盘自定View
于 2022-06-02 14:06:00 首次发布