自定义汽车仪表盘
自定义汽车仪表盘
效果图:
获取控件的宽高
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mCenterX = mWidth / 2f;
mCenterY = mHeight / 2f;
mRadius = (mHeight - offset * 2) / 2;
}
初始化画笔:
//最外层大圆弧的画笔
outerArcPaint = new Paint();
outerArcPaint.setStyle(Paint.Style.STROKE);
outerArcPaint.setStrokeWidth(mStrokeWidth);
outerArcPaint.setColor(Color.parseColor("#5555aa"));
outerArcPaint.setAntiAlias(true);//防止边缘锯齿
//最外层小圆弧的画笔
outerSmallArcPaint = new Paint();
outerSmallArcPaint.setAntiAlias(true);//防止边缘锯齿
outerSmallArcPaint.setStyle(Paint.Style.STROKE);
outerSmallArcPaint.setStrokeCap(Paint.Cap.ROUND);//设置线冒样式,取值有Cap.ROUND(圆形线冒)、Cap.SQUARE(方形线冒)、Paint.Cap.BUTT(无线冒)
outerSmallArcPaint.setStrokeWidth(dp2px(3));
SweepGradient sweepGradient = new SweepGradient(mCenterX, mCenterY, mColors, null);
outerSmallArcPaint.setShader(sweepGradient);//填充颜色
//内部圆的画笔
insideCirclePaint = new Paint();
insideCirclePaint.setColor(Color.parseColor("#27408B"));
insideCirclePaint.setStyle(Paint.Style.FILL);
insideCirclePaint.setAntiAlias(true);//防止边缘锯齿
//绘制速度值的画笔
speedPaint = new Paint();
speedPaint.setColor(Color.parseColor("#ff0000"));
speedPaint.setAntiAlias(true);//防止边缘锯齿
speedPaint.setStrokeWidth(4);
//刻度线的画笔
scaleLinePaint = new Paint();
scaleLinePaint.setStrokeWidth(4);
scaleLinePaint.setAntiAlias(true);//防止边缘锯齿
scaleLinePaint.setColor(Color.parseColor("#ECEFF1"));
//刻度数字的画笔
scaleTextPaint = new Paint();
scaleTextPaint.setTextSize(sp2px(16));
scaleTextPaint.setTypeface(Typeface.DEFAULT);
scaleTextPaint.setColor(Color.parseColor("#ECEFF1"));
scaleTextPaint.setAntiAlias(true);//防止边缘锯齿
mRectText = new Rect();
//绘制单位km/h的画笔
unitTextPaint = new Paint();
unitTextPaint.setColor(Color.parseColor("#ECEFF1"));
unitTextPaint.setAntiAlias(true);//防止边缘锯齿
unitTextPaint.setTypeface(Typeface.DEFAULT);
unitTextPaint.setTextSize(sp2px(16));
unitTextPaint.setTextAlign(Paint.Align.CENTER);
//指针的画笔
pointerPaint = new Paint();
pointerPaint.setStrokeCap(Paint.Cap.ROUND);//设置线的两端为圆弧
pointerPaint.setColor(Color.parseColor("#55aaaa"));
pointerPaint.setStrokeWidth(dp2px(3));
画圆弧
private void drawArc(Canvas canvas) {
//画外部大圆弧
RectF mRectFArc = new RectF((mWidth - mHeight) / 2 + offset, offset, mWidth - (mWidth - mHeight) / 2 - offset, mHeight - offset);
canvas.drawArc(mRectFArc, mStartAngle - 15, mSweepAngle + 30, false, outerArcPaint);
//画外部小圆弧
RectF mSmallRectFArc = new RectF((mWidth - mHeight) / 2 + offset + mLength1, offset + mLength1, mWidth - (mWidth - mHeight) / 2 - offset - mLength1, mHeight - offset - mLength1);
canvas.drawArc(mSmallRectFArc, mStartAngle - 15 + mSweepAngle + 30 - 360, 360 - (mSweepAngle + 30), false, outerSmallArcPaint);
//画内部中心圆
canvas.drawCircle(mCenterX, mCenterY, mRadius / 2, insideCirclePaint);
}
绘制文本
private void drawText(Canvas canvas) {
//绘制速度值
int xOffset = dp2px(22);
if (mVelocity >= 100) {
drawDigitalTube(canvas, mVelocity / 100, -xOffset);
drawDigitalTube(canvas, (mVelocity - 100) / 10, 0);
drawDigitalTube(canvas, mVelocity % 100 % 10, xOffset);
} else if (mVelocity >= 10) {
drawDigitalTube(canvas, -1, -xOffset);
drawDigitalTube(canvas, mVelocity / 10, 0);
drawDigitalTube(canvas, mVelocity % 10, xOffset);
} else {
drawDigitalTube(canvas, -1, -xOffset);
drawDigitalTube(canvas, -1, 0);
drawDigitalTube(canvas, mVelocity, xOffset);
}
//绘制单位km/h
canvas.drawText(mHeaderText, mWidth / 2, mHeight / 2 + unitTextPaint.getTextSize() + offset, unitTextPaint);
}
画刻度
private void drawScale(Canvas canvas) {
/**
* 画长刻度
* 画好起始角度的一条刻度后通过canvas绕着原点旋转来画剩下的长刻度
*/
double cos = Math.cos(Math.toRadians(mStartAngle - 180));
double sin = Math.sin(Math.toRadians(mStartAngle - 180));
int xOff = (mWidth - mHeight) / 2 + offset + mStrokeWidth / 2;
int yOff = offset - mStrokeWidth / 2;
float x0 = (float) (xOff + mRadius * (1 - cos));
float y0 = (float) (yOff + mRadius * (1 - sin));
float x1 = (float) (xOff + mRadius - (mRadius - mLength1) * cos);
float y1 = (float) (yOff + mRadius - (mRadius - mLength1) * sin);
canvas.save();
canvas.drawLine(x0, y0, x1, y1, scaleLinePaint);
float angle = mSweepAngle * 1f / mSection;
for (int i = 0; i < mSection; i++) {
canvas.rotate(angle, mCenterX, mCenterY);
canvas.drawLine(x0, y0, x1, y1, scaleLinePaint);
}
canvas.restore();
//画刻度读数
float α;
float[] p;
angle = mSweepAngle * 1f / mSection;
for (int i = 0; i <= mSection; i++) {
α = mStartAngle + angle * i;
p = getCoordinatePoint(mRadius - mLength2, α);
if (α % 360 > 135 && α % 360 < 225) {
scaleTextPaint.setTextAlign(Paint.Align.LEFT);
} else if ((α % 360 >= 0 && α % 360 < 45) || (α % 360 > 315 && α % 360 <= 360)) {
scaleTextPaint.setTextAlign(Paint.Align.RIGHT);
} else {
scaleTextPaint.setTextAlign(Paint.Align.CENTER);
}
scaleTextPaint.getTextBounds(mHeaderText, 0, mTexts[i].length(), mRectText);
int txtH = mRectText.height();
if (i <= 1 || i >= mSection - 1) {
canvas.drawText(mTexts[i], p[0], p[1] + txtH / 2, scaleTextPaint);
} else if (i == 3) {
canvas.drawText(mTexts[i], p[0] + txtH / 2, p[1] + txtH, scaleTextPaint);
} else if (i == mSection - 3) {
canvas.drawText(mTexts[i], p[0] - txtH / 2, p[1] + txtH, scaleTextPaint);
} else {
canvas.drawText(mTexts[i], p[0], p[1] + txtH, scaleTextPaint);
}
}
}
画指针
private void drawPointer(Canvas canvas) {
float θ = mStartAngle + mSweepAngle * (mVelocity - mMin) / (mMax - mMin); // 指针与水平线夹角
float[] p1 = getCoordinatePoint(mRadius - mStrokeWidth, θ);
float[] p2 = getCoordinatePoint(mRadius / 10 * 6, θ);
canvas.drawLine(p1[0], p1[1], p2[0], p2[1], pointerPaint);
}
下载地址:
源码下载
m0_46377012: import android.support.v7.app.AppCompatActivity;怎么报错了
脱贫致富un: 学习了