日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android實現儀表盤效果

瀏覽:193日期:2022-09-18 13:38:16

本文實例為大家分享了Android實現儀表盤效果的具體代碼,供大家參考,具體內容如下

儀表盤效果,圓弧可變色,效果圖如下:

Android實現儀表盤效果

通過自定義view實現,代碼如下:

public class DashboardView extends View { private int mRadius; // 畫布邊緣半徑(去除padding后的半徑) private int mStartAngle = 150; // 起始角度 private int mSweepAngle = 240; // 繪制角度 private int mMin = 1; // 最小值 private int mMax = 8; // 最大值 private int mSection = 8; // 值域(mMax-mMin)等分份數 private int mPortion = 3; // 一個mSection等分份數 private String mHeaderText = ''; // 表頭 private int mCreditValue = (int) 8.12; // 信用分 private int mSolidCreditValue = mCreditValue; // 信用分(設定后不變) private int mSparkleWidth; // 亮點寬度 private int mProgressWidth; // 進度圓弧寬度 private float mLength1; // 刻度頂部相對邊緣的長度 private int mCalibrationWidth; // 刻度圓弧寬度 private float mLength2; // 刻度讀數頂部相對邊緣的長度 private int mPadding; private float mCenterX, mCenterY; // 圓心坐標 private Paint mPaint; private RectF mRectFProgressArc; private RectF mRectFCalibrationFArc; private RectF mRectFTextArc; private Path mPath; private Rect mRectText; private String[] mTexts; private int mBackgroundColor; private int[] mBgColors; private boolean isAnimFinish = true; private float mAngleWhenAnim; public DashboardView(Context context) {this(context, null); } public DashboardView(Context context, AttributeSet attrs) {this(context, attrs, 0); } public DashboardView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(); } private void init() {mSparkleWidth = dp2px(10);mProgressWidth = dp2px(3);mCalibrationWidth = dp2px(10);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStrokeCap(Paint.Cap.ROUND);mRectFProgressArc = new RectF();mRectFCalibrationFArc = new RectF();mRectFTextArc = new RectF();mPath = new Path();mRectText = new Rect();mTexts = new String[]{'', 'Ⅳ', '', 'Ⅲ', '', 'Ⅱ', '', 'Ⅰ', ''};mBgColors = new int[]{ContextCompat.getColor(getContext(), R.color.color_red),ContextCompat.getColor(getContext(), R.color.color_orange),ContextCompat.getColor(getContext(), R.color.color_yellow),ContextCompat.getColor(getContext(), R.color.color_green),ContextCompat.getColor(getContext(), R.color.color_blue)};mBackgroundColor = mBgColors[0]; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mPadding = Math.max(Math.max(getPaddingLeft(), getPaddingTop()),Math.max(getPaddingRight(), getPaddingBottom()));setPadding(mPadding, mPadding, mPadding, mPadding);mLength1 = mPadding + mSparkleWidth / 2f + dp2px(8);mLength2 = mLength1 + mCalibrationWidth + dp2px(1) + dp2px(5);int width = resolveSize(dp2px(220), widthMeasureSpec);mRadius = (width - mPadding * 2) / 2;setMeasuredDimension(width, width - dp2px(30));mCenterX = mCenterY = getMeasuredWidth() / 2f;mRectFProgressArc.set(mPadding + mSparkleWidth / 2f,mPadding + mSparkleWidth / 2f,getMeasuredWidth() - mPadding - mSparkleWidth / 2f,getMeasuredWidth() - mPadding - mSparkleWidth / 2f);mRectFCalibrationFArc.set(mLength1 + mCalibrationWidth / 2f,mLength1 + mCalibrationWidth / 2f,getMeasuredWidth() - mLength1 - mCalibrationWidth / 2f,getMeasuredWidth() - mLength1 - mCalibrationWidth / 2f);mPaint.setTextSize(sp2px(10));mPaint.getTextBounds('0', 0, '0'.length(), mRectText);mRectFTextArc.set(mLength2 + mRectText.height(),mLength2 + mRectText.height(),getMeasuredWidth() - mLength2 - mRectText.height(),getMeasuredWidth() - mLength2 - mRectText.height()); } @SuppressLint('ResourceAsColor') @Override protected void onDraw(Canvas canvas) {super.onDraw(canvas);//canvas.drawColor(mBackgroundColor);//canvas.drawColor(R.color.color_blue);/** * 畫進度圓弧背景 */mPaint.setStrokeCap(Paint.Cap.ROUND);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mProgressWidth);mPaint.setAlpha(80);mPaint.setColor(mBackgroundColor);canvas.drawArc(mRectFProgressArc, mStartAngle + 1, mSweepAngle - 2, false, mPaint);mPaint.setAlpha(255);if (isAnimFinish) { /** * 畫進度圓弧(起始到信用值) */ mPaint.setShader(generateSweepGradient()); mPaint.setColor(mBackgroundColor); canvas.drawArc(mRectFProgressArc, mStartAngle + 1, calculateRelativeAngleWithValue(mCreditValue) - 2, false, mPaint); /** * 畫指示亮點 */ float[] point = getCoordinatePoint( mRadius - mSparkleWidth / 2f, mStartAngle + calculateRelativeAngleWithValue(mCreditValue) ); mPaint.setStyle(Paint.Style.FILL); mPaint.setShader(generateRadialGradient(point[0], point[1])); mPaint.setColor(mBackgroundColor); canvas.drawCircle(point[0], point[1], mSparkleWidth / 2f, mPaint);} else { /** * 畫進度圓弧(起始到信用值) */ mPaint.setShader(generateSweepGradient()); mPaint.setColor(mBackgroundColor); canvas.drawArc(mRectFProgressArc, mStartAngle + 1, mAngleWhenAnim - mStartAngle - 2, false, mPaint); /** * 畫指示亮點 */ float[] point = getCoordinatePoint( mRadius - mSparkleWidth / 2f, mAngleWhenAnim ); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(mBackgroundColor); mPaint.setShader(generateRadialGradient(point[0], point[1])); canvas.drawCircle(point[0], point[1], mSparkleWidth / 2f, mPaint);}/** * 畫刻度圓弧 */mPaint.setShader(null);mPaint.setStyle(Paint.Style.STROKE);mPaint.setColor(Color.WHITE);mPaint.setAlpha(80);mPaint.setStrokeCap(Paint.Cap.SQUARE);mPaint.setStrokeWidth(mCalibrationWidth);mPaint.setColor(mBackgroundColor);canvas.drawArc(mRectFCalibrationFArc, mStartAngle + 3, mSweepAngle - 6, false, mPaint);/** * 畫長刻度 * 畫好起始角度的一條刻度后通過canvas繞著原點旋轉來畫剩下的長刻度 */mPaint.setStrokeCap(Paint.Cap.ROUND);mPaint.setStrokeWidth(dp2px(2));mPaint.setAlpha(120);mPaint.setColor(mBackgroundColor);float x0 = mCenterX;float y0 = mPadding + mLength1 + dp2px(1);float x1 = mCenterX;float y1 = y0 + mCalibrationWidth;// 逆時針到開始處canvas.save();canvas.drawLine(x0, y0, x1, y1, mPaint);float degree = mSweepAngle / mSection;for (int i = 0; i < mSection / 2; i++) { canvas.rotate(-degree, mCenterX, mCenterY); canvas.drawLine(x0, y0, x1, y1, mPaint);}canvas.restore();// 順時針到結尾處canvas.save();for (int i = 0; i < mSection / 2; i++) { canvas.rotate(degree, mCenterX, mCenterY); canvas.drawLine(x0, y0, x1, y1, mPaint);}canvas.restore();/** * 畫短刻度 * 同樣采用canvas的旋轉原理 */mPaint.setStrokeWidth(dp2px(1));mPaint.setAlpha(80);mPaint.setColor(mBackgroundColor);float x2 = mCenterX;float y2 = y0 + mCalibrationWidth - dp2px(2);// 逆時針到開始處canvas.save();canvas.drawLine(x0, y0, x2, y2, mPaint);degree = mSweepAngle / (mSection * mPortion);for (int i = 0; i < (mSection * mPortion) / 2; i++) { canvas.rotate(-degree, mCenterX, mCenterY); canvas.drawLine(x0, y0, x2, y2, mPaint);}canvas.restore();// 順時針到結尾處canvas.save();for (int i = 0; i < (mSection * mPortion) / 2; i++) { canvas.rotate(degree, mCenterX, mCenterY); canvas.drawLine(x0, y0, x2, y2, mPaint);}canvas.restore();/** * 畫長刻度讀數 * 添加一個圓弧path,文字沿著path繪制 */mPaint.setTextSize(sp2px(10));mPaint.setTextAlign(Paint.Align.LEFT);mPaint.setStyle(Paint.Style.FILL);mPaint.setAlpha(160);mPaint.setColor(mBackgroundColor);for (int i = 0; i < mTexts.length; i++) { mPaint.getTextBounds(mTexts[i], 0, mTexts[i].length(), mRectText); // 粗略把文字的寬度視為圓心角2*θ對應的弧長,利用弧長公式得到θ,下面用于修正角度 float θ = (float) (180 * mRectText.width() / 2 / (Math.PI * (mRadius - mLength2 - mRectText.height()))); mPath.reset(); mPath.addArc( mRectFTextArc, mStartAngle + i * (mSweepAngle / mSection) - θ, // 正起始角度減去θ使文字居中對準長刻度 mSweepAngle ); canvas.drawTextOnPath(mTexts[i], mPath, 0, 0, mPaint);}/** * 畫實時度數值 */mPaint.setAlpha(255);mPaint.setTextSize(sp2px(50));mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setColor(mBackgroundColor);//String value = String.valueOf(mSolidCreditValue);String value = '';if (mSolidCreditValue > 6) { //'Ⅳ', '', 'Ⅲ', '', 'Ⅱ', '', 'Ⅰ', value = 'Ⅰ';} else if (5 < mSolidCreditValue && mSolidCreditValue <= 6) { value = 'Ⅱ';} else if (4 < mSolidCreditValue && mSolidCreditValue <= 5) { value = 'Ⅲ';} else if (3 < mSolidCreditValue && mSolidCreditValue <= 4) { value = 'Ⅳ';}canvas.drawText(value, mCenterX, mCenterY + dp2px(30), mPaint);/** * 畫表頭 */mPaint.setAlpha(160);mPaint.setTextSize(sp2px(12));mPaint.setColor(Color.BLACK);canvas.drawText(mHeaderText, mCenterX, mCenterY - dp2px(20), mPaint);/** * 畫描述 */mPaint.setAlpha(255);mPaint.setTextSize(sp2px(20));mPaint.setColor(mBackgroundColor);canvas.drawText(calculateCreditDescription(), mCenterX, mCenterY + dp2px(55), mPaint);/** * 畫評估時間 */mPaint.setAlpha(160);mPaint.setTextSize(sp2px(10));mPaint.setColor(Color.BLACK);canvas.drawText(getFormatTimeStr(), mCenterX, mCenterY + dp2px(70), mPaint); } private int dp2px(int dp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,Resources.getSystem().getDisplayMetrics()); } private int sp2px(int sp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,Resources.getSystem().getDisplayMetrics()); } private SweepGradient generateSweepGradient() {SweepGradient sweepGradient = new SweepGradient(mCenterX, mCenterY,new int[]{Color.argb(0, 255, 255, 255), Color.argb(200, 255, 255, 255)},new float[]{0, calculateRelativeAngleWithValue(mCreditValue) / 360});Matrix matrix = new Matrix();matrix.setRotate(mStartAngle - 1, mCenterX, mCenterY);sweepGradient.setLocalMatrix(matrix);return sweepGradient; } private RadialGradient generateRadialGradient(float x, float y) {return new RadialGradient(x, y, mSparkleWidth / 2f,new int[]{Color.argb(255, 255, 255, 255), Color.argb(80, 255, 255, 255)},new float[]{0.4f, 1},Shader.TileMode.CLAMP); } private float[] getCoordinatePoint(float radius, float angle) {float[] point = new float[2];double arcAngle = Math.toRadians(angle); //將角度轉換為弧度if (angle < 90) { point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius); point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);} else if (angle == 90) { point[0] = mCenterX; point[1] = mCenterY + radius;} else if (angle > 90 && angle < 180) { arcAngle = Math.PI * (180 - angle) / 180.0; point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius); point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);} else if (angle == 180) { point[0] = mCenterX - radius; point[1] = mCenterY;} else if (angle > 180 && angle < 270) { arcAngle = Math.PI * (angle - 180) / 180.0; point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius); point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);} else if (angle == 270) { point[0] = mCenterX; point[1] = mCenterY - radius;} else { arcAngle = Math.PI * (360 - angle) / 180.0; point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius); point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);}return point; } /** * 相對起始角度計算所對應的角度大小 */ private float calculateRelativeAngleWithValue(int value) {float degreePerSection = 1f * mSweepAngle / mSection;if (value > 6) { return 8 * degreePerSection + 2 * degreePerSection / 250 * (value - 6);} else if (value > 5) { return 6 * degreePerSection + 2 * degreePerSection / 50 * (value - 5);} else if (value > 4) { return 4 * degreePerSection + 2 * degreePerSection / 50 * (value - 4);} else if (value > 3) { return 2 * degreePerSection + 2 * degreePerSection / 50 * (value - 3);} else { return 2 * degreePerSection / 200 * (value - 1);} } /** * 信用分對應描述 */ private String calculateCreditDescription() {if (mSolidCreditValue > 6) { return '';} else if (mSolidCreditValue > 5) { return '';} else if (mSolidCreditValue > 4) { return '';} else if (mSolidCreditValue > 3) { return '';}return ''; } private SimpleDateFormat mDateFormat; private String getFormatTimeStr() {if (mDateFormat == null) { mDateFormat = new SimpleDateFormat('yyyy.MM.dd HH:mm', Locale.CHINA);}return String.format('', mDateFormat.format(new Date()));//return String.format('監測日期:%s', '2020-05-04'); } public int getCreditValue() {return mCreditValue; } /** * 設置值 * * @param creditValue */ public void setCreditValue(int creditValue) {if (mSolidCreditValue == creditValue || creditValue < mMin || creditValue > mMax) { return;}mSolidCreditValue = creditValue;mCreditValue = creditValue;postInvalidate(); } /** * 設置并播放動畫 * * @param creditValue 值 */ public void setCreditValueWithAnim(int creditValue) {if (creditValue < mMin || creditValue > mMax || !isAnimFinish) { return;}mSolidCreditValue = creditValue;ValueAnimator creditValueAnimator = ValueAnimator.ofInt(1, mSolidCreditValue);creditValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {mCreditValue = (int) animation.getAnimatedValue();postInvalidate(); }});// 計算最終值對應的角度,以掃過的角度的線性變化來播放動畫float degree = calculateRelativeAngleWithValue(mSolidCreditValue);ValueAnimator degreeValueAnimator = ValueAnimator.ofFloat(mStartAngle, mStartAngle + degree);degreeValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {mAngleWhenAnim = (float) animation.getAnimatedValue(); }});@SuppressLint('ObjectAnimatorBinding') ObjectAnimator colorAnimator = ObjectAnimator.ofInt(this, 'mBackgroundColor', mBgColors[0], mBgColors[0]);// 實時信用值對應的背景色的變化long delay = 1000;if (mSolidCreditValue > 6) { colorAnimator.setIntValues(mBgColors[0], mBgColors[1], mBgColors[2], mBgColors[3], mBgColors[4]); delay = 3000;} else if (mSolidCreditValue > 5) { colorAnimator.setIntValues(mBgColors[0], mBgColors[1], mBgColors[2], mBgColors[3]); delay = 2500;} else if (mSolidCreditValue > 4) { colorAnimator.setIntValues(mBgColors[0], mBgColors[1], mBgColors[2]); delay = 2000;} else if (mSolidCreditValue > 3) { colorAnimator.setIntValues(mBgColors[0], mBgColors[1]); delay = 1500;}colorAnimator.setEvaluator(new ArgbEvaluator());colorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {mBackgroundColor = (int) animation.getAnimatedValue(); }});AnimatorSet animatorSet = new AnimatorSet();animatorSet.setDuration(delay).playTogether(creditValueAnimator, degreeValueAnimator, colorAnimator);animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) {super.onAnimationStart(animation);isAnimFinish = false; } @Override public void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);isAnimFinish = true; } @Override public void onAnimationCancel(Animator animation) {super.onAnimationCancel(animation);isAnimFinish = true; }});animatorSet.start(); }}

在color中添加顏色值:

<color name='color_red'>#FF5722</color><color name='color_orange'>#FF9800</color><color name='color_yellow'>#FFC107</color><color name='color_green'>#3FB830</color><color name='color_blue'>#00BAED</color>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩精品免费视频人成| 国产一区2区| 手机精品视频在线观看| 久久香蕉精品香蕉| 91久久中文| 精品国产亚洲一区二区三区大结局| 国产成人久久| 午夜欧美巨大性欧美巨大| 在线手机中文字幕| 少妇精品久久久一区二区三区| 高清不卡一区| 国产丝袜一区| 久久夜色精品| 国产精品老牛| 亚洲一区二区毛片| 日韩 欧美一区二区三区| 国产一区二区三区不卡av | 国产精品99一区二区| 精品三区视频| 久久av电影| 麻豆一区二区三| 欧美国产日本| 久久影视三级福利片| 国产福利一区二区精品秒拍 | 亚洲三级欧美| 国产精品久久久久久久免费软件| 国精品产品一区| 免费日韩精品中文字幕视频在线| 麻豆国产欧美日韩综合精品二区| 欧美日韩国产综合网| 福利一区在线| 人人精品久久| 亚洲黄色影院| av高清不卡| 国产精品欧美大片| 日韩中文字幕区一区有砖一区 | 欧美精品高清| 国产精品**亚洲精品| 美女精品网站| 在线国产一区| 99久久99久久精品国产片果冰| 久久精品国产成人一区二区三区| 爽爽淫人综合网网站| av亚洲在线观看| 欧美精品激情| 亚洲国产一区二区在线观看 | 欧美91在线| 国产精品久久亚洲不卡| 日韩精品一区二区三区中文在线 | 日韩1区2区3区| 在线视频亚洲欧美中文| 欧美另类专区| 亚洲有吗中文字幕| 在线亚洲国产精品网站| 自由日本语亚洲人高潮| 国产精品普通话对白| 欧美综合另类| 激情欧美一区| 亚洲在线观看| 日韩精品久久久久久| 日韩高清在线不卡| 国产亚洲人成a在线v网站| 国产视频网站一区二区三区| 久久中文在线| 久久国产小视频| 亚洲制服少妇| 国产精品亲子伦av一区二区三区| 国产成人免费精品| 国产二区精品| 国产日韩欧美在线播放不卡| 日韩一区亚洲二区| 日韩电影在线视频| 黄色亚洲精品| 国产精品片aa在线观看| 国产韩日影视精品| 日韩精品乱码av一区二区| 福利一区和二区| 爽爽淫人综合网网站| 精品视频网站| 亚洲欧洲一区二区天堂久久| 国产精品夜夜夜| 伊人久久大香线蕉av不卡| 91麻豆精品激情在线观看最新| 欧美激情视频一区二区三区免费| 久久精品二区三区| 国产精品久久久久久久久久齐齐| 久久免费国产| 蜜桃久久精品一区二区| 高清在线一区| 日韩av中文字幕一区二区 | 亚洲成a人片| 国产精品久久久久久模特| av不卡在线看| 香蕉视频亚洲一级| 麻豆国产欧美日韩综合精品二区| 亚洲欧美久久久| 最近高清中文在线字幕在线观看1| 日韩精品免费观看视频| 国产亚洲一级| 九一国产精品| 精品视频一区二区三区四区五区 | 亚洲欧美日韩视频二区| 久久精品国产亚洲aⅴ| 亚洲理论在线| 国产日韩专区| 亚洲激情久久| 精品在线99| 国产成人免费| 精品一区二区三区在线观看视频 | 久久精品系列| 久久精品999| 中文字幕日韩亚洲| 中文字幕成人| 中文字幕日韩高清在线| 日韩亚洲精品在线| 99久久夜色精品国产亚洲狼 | 国产96在线亚洲| 久久精品国产亚洲aⅴ| 麻豆免费精品视频| 精品视频在线观看网站| 91日韩在线| 亚洲www免费| 欧美日韩激情| 久久国产精品久久久久久电车| 成人av二区| 911亚洲精品| 成人国产精品久久| 成人国产精品一区二区免费麻豆| 日韩av片子| 亚洲精品123区| 日韩在线观看一区二区三区| 日本国产亚洲| 精品国产亚洲日本| 欧美va亚洲va日韩∨a综合色| 免费久久精品视频| 精品国产亚洲一区二区在线观看| 999久久久91| 热久久久久久| 波多野结衣一区| 老牛国内精品亚洲成av人片| 不卡一区综合视频| 国产精品视频首页| 欧美日韩第一| 午夜久久av | 日本久久二区| 欧美精品aa| 激情综合网五月| 欧美黄色精品| 欧美午夜不卡影院在线观看完整版免费| 一区二区亚洲视频| 日本蜜桃在线观看视频| 亚洲欧美久久精品| 日韩免费在线| 国产在线日韩精品| 亚洲精品高潮| 亚洲人成在线网站| 久久国产麻豆精品| 免费在线观看精品| 99成人在线视频| 国产一区丝袜| 亚洲一区欧美| 精品中文一区| 国产精品99免费看| 久久精品在线| 日韩中文在线电影| 色网在线免费观看| 国产69精品久久| 国产+成+人+亚洲欧洲在线| 国产精品**亚洲精品| 麻豆精品视频在线| 黄色网一区二区| 六月婷婷综合| 午夜电影亚洲| 免费久久99精品国产自在现线| 99在线观看免费视频精品观看| 日韩中文欧美| 国产一区久久| 在线亚洲激情| 日韩精品第二页| 国产精品99精品一区二区三区∴| 久久爱www.| 久久国产影院| 蜜桃久久av一区| 国产精品久久久久久久久免费高清| 精品国产精品国产偷麻豆| 日韩大片免费观看| 99国产精品久久久久久久 | 婷婷成人av| 好看的av在线不卡观看| 美女视频黄免费的久久| 日本在线成人| 亚洲精品第一| 蜜桃久久久久久久| 99国产精品99久久久久久粉嫩| 一本一道久久a久久精品蜜桃| 免费观看不卡av| 夜夜嗨网站十八久久| 99国产成+人+综合+亚洲欧美| 2023国产精品久久久精品双| 99视频精品全国免费|