国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View仿支付寶芝麻信用分儀表盤

2019-12-12 05:22:15
字體:
來源:轉載
供稿:網友

先看下iOS的芝麻信用分截圖

這是我做的效果,還是有點差距的

支付寶9.9版本芝麻信用分的實現

首先初始化各種畫筆,默認的sizepadding,小圓點.

(因為實在找不到原版芝麻信用的帶點模糊效果的小圓點,所以只好用這個代替)

//View的默認大小defaultSize = dp2px(250);//默認Padding大小arcDistance = dp2px(14);//外層圓環畫筆mMiddleArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mMiddleArcPaint.setStrokeWidth(8);mMiddleArcPaint.setColor(Color.WHITE);mMiddleArcPaint.setStyle(Paint.Style.STROKE);mMiddleArcPaint.setAlpha(80);//內層圓環畫筆mInnerArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mInnerArcPaint.setStrokeWidth(30);mInnerArcPaint.setColor(Color.WHITE);mInnerArcPaint.setAlpha(80);mInnerArcPaint.setStyle(Paint.Style.STROKE);//正中間字體畫筆mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mTextPaint.setColor(Color.WHITE);mTextPaint.setTextAlign(Paint.Align.CENTER);//圓環大刻度畫筆mCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mCalibrationPaint.setStrokeWidth(4);mCalibrationPaint.setStyle(Paint.Style.STROKE);mCalibrationPaint.setColor(Color.WHITE);mCalibrationPaint.setAlpha(120);//圓環小刻度畫筆mSmallCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mSmallCalibrationPaint.setStrokeWidth(1);mSmallCalibrationPaint.setStyle(Paint.Style.STROKE);mSmallCalibrationPaint.setColor(Color.WHITE);mSmallCalibrationPaint.setAlpha(130);//圓環刻度文本畫筆mCalibrationTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mCalibrationTextPaint.setTextSize(30);mCalibrationTextPaint.setColor(Color.WHITE);//外層進度畫筆mArcProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mArcProgressPaint.setStrokeWidth(8);mArcProgressPaint.setColor(Color.WHITE);mArcProgressPaint.setStyle(Paint.Style.STROKE);mArcProgressPaint.setStrokeCap(Paint.Cap.ROUND);//外層圓環上小圓點Bitmap畫筆mBitmapPaint = new Paint();mBitmapPaint.setStyle(Paint.Style.FILL);mBitmapPaint.setAntiAlias(true);//初始化小圓點圖片bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_circle);//當前點的實際位置pos = new float[2];//當前點的tangent值tan = new float[2];matrix = new Matrix();

代碼很簡單,就是各種初始化,往下看.

View的測量,主要在給設置warp_content時候給定一個默認寬高值.

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ setMeasuredDimension(resolveMeasure(widthMeasureSpec, defaultSize),   resolveMeasure(heightMeasureSpec, defaultSize));}//根據傳入的值進行測量public int resolveMeasure(int measureSpec, int defaultSize){ int result = 0; int specSize = MeasureSpec.getSize(measureSpec); switch (MeasureSpec.getMode(measureSpec))  {   case MeasureSpec.UNSPECIFIED:    result = defaultSize;    break;   case MeasureSpec.AT_MOST:    //設置warp_content時設置默認值    result = Math.min(specSize, defaultSize);    break;   case MeasureSpec.EXACTLY:    //設置math_parent 和設置了固定寬高值    break;   default:    result = defaultSize;  }  return result;}

然后確定View的寬高后的回調方法.

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh){  super.onSizeChanged(w, h, oldw, oldh);  width = w;  height = h;  radius = width / 2; //外層圓環矩形 mMiddleRect = new RectF(defaultPadding, defaultPadding,width - defaultPadding, height - defaultPadding); //內層圓環矩形 mInnerRect = new RectF(defaultPadding + arcDistance, defaultPadding + arcDistance,width - defaultPadding - arcDistance, height - defaultPadding - arcDistance); // 外層進度矩形 mMiddleProgressRect = new RectF(defaultPadding, defaultPadding,width - defaultPadding, height - defaultPadding);}

這里就是初始化圓弧所需要的矩形實現,下邊開始進行重點,繪制,

繪制外層的圓弧,很簡單, 圓弧的起始角度,角度.

private void drawMiddleArc(Canvas canvas){ canvas.drawArc(mMiddleRect, mStartAngle, mEndAngle, false, mMiddleArcPaint);}

繪制內層圓弧

private void drawInnerArc(Canvas canvas){  canvas.drawArc(mInnerRect, mStartAngle, mEndAngle, false, mInnerArcPaint);}

繪制內層圓弧上的小刻度,畫布旋轉到圓弧左下角起點,計算出每條刻度線的起始點后,整個圓弧是210度,

每6角度繪制一條刻度線.

private void drawSmallCalibration(Canvas canvas){  //旋轉畫布  canvas.save();  canvas.rotate(-105, radius, radius);  //計算刻度線的起點結束點  int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);  int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());  for (int i = 0; i <= 35; i++) {   //每旋轉6度繪制一個小刻度   canvas.drawLine(radius, startDst, radius, endDst, mSmallCalibrationPaint);   canvas.rotate(6, radius, radius); } canvas.restore();}

繪制內層圓弧上的大刻度,350, 550, 600,650, 700, 950,對應的信用分值,

一樣旋轉畫布,計算刻度線的起始點,計算出每次旋轉的角度,每35度旋轉一次,依次繪制對應的大刻度線,

然后繪制對應的文本內容,使用paintmeasureText方法測量出文本的長度,依次繪制對應的文本內容.

private void drawCalibrationAndText(Canvas canvas){  //旋轉畫布進行繪制對應的刻度  canvas.save();  canvas.rotate(-105, radius, radius);  //計算刻度線的起點結束點  int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);  int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());  //刻度旋轉的角度  int rotateAngle = 210 / 10;  for (int i = 1; i < 12; i++) {   if (i % 2 != 0)   {    canvas.drawLine(radius, startDst, radius, endDst, mCalibrationPaint);   }   // 測量文本的長度  float textLen = mCalibrationTextPaint.measureText(sesameStr[i - 1]); canvas.drawText(sesameStr[i - 1], radius - textLen / 2, endDst + 40, mCalibrationTextPaint);  canvas.rotate(rotateAngle, radius, radius); } canvas.restore();}

繪制中間的信用分值,信用等級,評估時間等文本,這個比較簡單,直接drawText,依次高低排列繪制即可.

private void drawCenterText(Canvas canvas){  //繪制Logo  mTextPaint.setTextSize(30);  canvas.drawText("BETA", radius, radius - 130, mTextPaint);  //繪制信用分數  mTextPaint.setTextSize(200);  mTextPaint.setStyle(Paint.Style.STROKE);  canvas.drawText(String.valueOf(mMinNum), radius, radius + 70, mTextPaint);  //繪制信用級別  mTextPaint.setTextSize(80);  canvas.drawText(sesameLevel, radius, radius + 160, mTextPaint);  //繪制評估時間  mTextPaint.setTextSize(30);  canvas.drawText(evaluationTime, radius, radius + 205, mTextPaint);}

繪制最外層的進度,這里使用的Path添加要繪制的圓弧,因為需要去不斷的計算坐標點,主要用到了PathMeasure這個類,將繪制的圓弧加入到path中,

當前點的實際位置

private float[] pos;

當前的tangent值

private float[] tan;

獲取路徑的終點的正切值和坐標,然后根據坐標點繪制小圓點

PathMeasure pathMeasure = new PathMeasure(path, false);pathMeasure.getPosTan(pathMeasure.getLength() * 1, pos, tan);
private void drawRingProgress(Canvas canvas){  Path path = new Path();  path.addArc(mMiddleProgressRect, mStartAngle, mCurrentAngle); PathMeasure pathMeasure = new PathMeasure(path, false); pathMeasure.getPosTan(pathMeasure.getLength() * 1, pos, tan);  matrix.reset();  matrix.postTranslate(pos[0] - bitmap.getWidth() / 2, pos[1] - bitmap.getHeight() / 2); canvas.drawPath(path, mArcProgressPaint);  //起始角度不為0時候才進行繪制小圓點  if (mCurrentAngle == 0)    return;  canvas.drawBitmap(bitmap, matrix, mBitmapPaint);  mBitmapPaint.setColor(Color.WHITE);  canvas.drawCircle(pos[0], pos[1], 8, mBitmapPaint);}

好了,到這里所有繪制完畢了,接下來讓圓弧進度條動起來吧,使用ValueAnimator,進度條動畫定義了圓弧進度條的開始角度mCurrentAngle,圓弧角度mTotalAngle,數值動畫定義了初始化minNum=0maxNum根據傳入的數值進行計算.

public void startAnim(){  ValueAnimator mAngleAnim = ValueAnimator.ofFloat(mCurrentAngle, mTotalAngle);  mAngleAnim.setInterpolator(new AccelerateDecelerateInterpolator());  mAngleAnim.setDuration(3000);  mAngleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){   @Override   public void onAnimationUpdate(ValueAnimator valueAnimator){    mCurrentAngle = (float) valueAnimator.getAnimatedValue();    postInvalidate();  } });  mAngleAnim.start();  ValueAnimator mNumAnim = ValueAnimator.ofInt(mMinNum, mMaxNum); mNumAnim.setDuration(3000);  mNumAnim.setInterpolator(new LinearInterpolator());  mNumAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  @Override   public void onAnimationUpdate(ValueAnimator valueAnimator){    mMinNum = (int) valueAnimator.getAnimatedValue();    postInvalidate();  } });  mNumAnim.start();}

最后根據傳入的信用分值計算圓弧進度條所到的角度.

public void setSesameValues(int values){  if (values <= 350){   mMaxNum = values;   mTotalAngle = 0f;   sesameLevel = "信用較差";   evaluationTime = "評估時間:" + getCurrentTime();  } else if (values <= 550){   mMaxNum = values;   mTotalAngle = (values - 350) * 80 / 400f + 2;   sesameLevel = "信用較差";   evaluationTime = "評估時間:" + getCurrentTime();  } else if (values <= 700) {   mMaxNum = values;   if (values > 550 && values <= 600){    sesameLevel = "信用中等";   } else if (values > 600 && values <= 650){    sesameLevel = "信用良好";   } else {    sesameLevel = "信用優秀";   }   mTotalAngle = (values - 550) * 120 / 150f + 43;   evaluationTime = "評估時間:" + getCurrentTime();  } else if (values <= 950){   mMaxNum = values;   mTotalAngle = (values - 700) * 40 / 250f + 170;   sesameLevel = "信用極好";   evaluationTime = "評估時間:" + getCurrentTime();  } else{   mTotalAngle = 240f;  }  startAnim();}

總結

這篇文章只分析了新版的實現過程,舊版的的實現思路也差不多,代碼也不復雜。希望這篇文章對大家開發Android能有所幫助,如果有疑問可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 寻乌县| 绍兴市| 财经| 垣曲县| 吉木萨尔县| 汉寿县| 太谷县| 阿克苏市| 宁德市| 马山县| 铜山县| 临洮县| 财经| 马公市| 油尖旺区| 扬州市| 兴安盟| 扎赉特旗| 革吉县| 汝阳县| 台中县| 海城市| 贺州市| 滨海县| 海口市| 曲沃县| 星子县| 鹤峰县| 定边县| 太保市| 松阳县| 娄底市| 荔波县| 山阳县| 阜城县| 台北市| 菏泽市| 西青区| 奇台县| 公安县| 当雄县|