一、概述
今天接著研究paint畫筆极阅,實現(xiàn)圓環(huán)百分比進度變化效果胃碾,效果圖如下:
二、思路分析
這個效果其實和前面的qq計步器實現(xiàn)思路差不多筋搏,那個是兩個圓弧仆百,這個里面是不動的圓形,外面是圓弧奔脐。
2.1自定義屬性
自定義屬性包含內(nèi)圓畫筆的顏色俄周,畫筆描邊的粗細,外面圓弧的畫筆顏色髓迎,里面中間百分比文字的大小和顏色峦朗。
attrs文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressView">
<attr name="innerCicleColor" format="color"></attr>
<attr name="outCicleColor" format="color"></attr>
<attr name="roundWidth" format="dimension"></attr>
<attr name="progressTextColor" format="color"></attr>
<attr name="progressTextSize" format="dimension"></attr>
</declare-styleable>
</resources>
自定義類構(gòu)造函數(shù)
//獲取屬性
public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleProgressView);
mInnerColor = a.getColor(R.styleable.CircleProgressView_innerCicleColor,mInnerColor);
mOutColor = a.getColor(R.styleable.CircleProgressView_outCicleColor,mOutColor);
mRoundWidth = (int)a.getDimension(R.styleable.CircleProgressView_roundWidth,dp2px(mRoundWidth));
mTextSize = a.getDimensionPixelSize(R.styleable.CircleProgressView_progressTextSize,sp2px(mTextSize));
a.recycle();
mInnerPaint = new Paint();
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setAntiAlias(true); //抗鋸齒
mInnerPaint.setStrokeWidth(mRoundWidth);
mInnerPaint.setStyle(Paint.Style.STROKE); //空心圓
mOutPaint = new Paint();
mOutPaint.setColor(mOutColor);
mOutPaint.setAntiAlias(true); //抗鋸齒
mOutPaint.setStrokeWidth(mRoundWidth);
mOutPaint.setStyle(Paint.Style.STROKE); //空心圓
mTextPaint = new Paint();
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(mTextColor);
}
2.2在ondraw方法中繪制
//繪制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪制內(nèi)圓
int center = getWidth()/2;
canvas.drawCircle(center,center,center-mRoundWidth/2,mInnerPaint);
//繪制外圓
RectF rectF = new RectF(mRoundWidth/2,mRoundWidth/2,getWidth()-mRoundWidth/2,getHeight()-mRoundWidth/2);
if (mCurrentProgress == 0){
return;
}
float percent = (float)mCurrentProgress/mMax;
canvas.drawArc(rectF,0,percent*360,false,mOutPaint); //false 表示不包括圓心
//繪制文字
String textString = ((int)(percent*100))+"%";
// String textString = (mMax - (mCurrentProgress-1))+"";
Rect bounds = new Rect();
mTextPaint.getTextBounds(textString,0,textString.length(),bounds);
int dy = (mTextPaint.getFontMetricsInt().bottom-mTextPaint.getFontMetricsInt().top)/2-mTextPaint.getFontMetricsInt().bottom;
int baseLine = getHeight()/2 + dy;
canvas.drawText(textString,getWidth()/2-bounds.width()/2,baseLine,mTextPaint);
}
對圓的半徑的計算不理解的可以參考這邊文章:
Canvas drawCircle Rect邊框問題
onmeasure方法就不介紹了,前面說了很多了排龄。
2.3暴露給用戶方法動態(tài)改變百分比的值
//暴露給外面調(diào)用 設(shè)置當前值 不斷調(diào)用ondraw方法
public synchronized void setCurrentProgress(int currentProgress) {
this.mCurrentProgress = currentProgress;
invalidate();
}
在mainActivity中用設(shè)置屬性動畫波势,監(jiān)聽值的變化,調(diào)用此方法橄维,繪制界面:
circleProgressView.setMax(4000);
ValueAnimator objectAnimator = ObjectAnimator.ofFloat(1,4000);
objectAnimator.setDuration(5000);
objectAnimator.start();
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
circleProgressView.setCurrentProgress((int) progress);
}
});
三尺铣、結(jié)語
當然,這個效果也可以擴展争舞,你可以做成別的效果凛忿,例如倒計時,代碼稍微改動下就行了竞川。分析完畢店溢,代碼地址:
http://pan.baidu.com/s/1o80TQm2