一李根、概述
今天要講的效果是類似qq計(jì)步器的效果,先看下效果圖:
qq計(jì)步器效果.gif
二几睛、思路分析
看圖說話房轿,圖中有兩個(gè)圓弧,一個(gè)背景圓弧所森,一個(gè)能動(dòng)態(tài)變化的圓弧囱持,中間有記錄步數(shù)的文字。三個(gè)對(duì)象焕济,每個(gè)對(duì)象有各自的屬性纷妆。然后就是設(shè)置各自對(duì)象的大小和各自對(duì)象的繪制了。
2.1自定義屬性
attrs文件中的代碼:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="QQStepView">
<!--畫筆顏色-->
<attr name="outColor" format="color"></attr>
<attr name="innerColor" format="color"></attr>
<!--畫筆的寬度大小-->
<attr name="boderWidth" format="dimension"></attr>
<!--文字的顏色和大小-->
<attr name="stepColor" format="color"></attr>
<attr name="stepSeize" format="dimension"></attr>
</declare-styleable>
</resources>
定義了背景圓弧畫筆和前景圓弧畫筆的顏色及寬度晴弃,還有中間文字的顏色和尺寸打小掩幢,在構(gòu)造函數(shù)中初始化逊拍。
2.2構(gòu)造函數(shù)代碼
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.QQStepView);
mOutColor = a.getColor(R.styleable.QQStepView_outColor,mOutColor);
mInnerColor = a.getColor(R.styleable.QQStepView_innerColor,mInnerColor);
mStepTextSize = a.getDimensionPixelSize(R.styleable.QQStepView_stepSeize,sp2px(mStepTextSize));
mBorderWidth = (int)a.getDimension(R.styleable.QQStepView_boderWidth,mBorderWidth);
mStepTextColor = a.getColor(R.styleable.QQStepView_stepColor,mStepTextColor);
a.recycle();
mOutPaint = new Paint();
mOutPaint.setAntiAlias(true); //抗鋸齒
mOutPaint.setColor(mOutColor);
mOutPaint.setStrokeWidth(mBorderWidth);
mOutPaint.setStyle(Paint.Style.STROKE);
mInnerPaint = new Paint();
mInnerPaint.setAntiAlias(true); //抗鋸齒
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setStrokeWidth(mBorderWidth);
mInnerPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint();
mTextPaint.setColor(mStepTextColor);
mTextPaint.setTextSize(mStepTextSize);
構(gòu)造函數(shù)沒啥好講的,都是套路
2.3onMeasure方法設(shè)置控件寬高
//onMeasure()
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//寬高不一致 取最小值 確保是一個(gè)正方形
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width>height?height:width,width>height?height:width);
}
2.4onDraw方法中對(duì)幾個(gè)對(duì)象進(jìn)行繪制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫外圓弧 际邻,內(nèi)圓弧 芯丧,文字
int center = getWidth()/2;
int radius = center - mBorderWidth/2; //外切圓壓住描邊的中間
//指定圓弧的外輪廓矩形區(qū)域。比較易懂
RectF rectF = new RectF(center - radius, center - radius, center
+ radius, center + radius);
canvas.drawArc(rectF,135,270,false,mOutPaint);
if (mStepMax==0){
return;
}
//這里要強(qiáng)制轉(zhuǎn)換為float型的
float sweepAngle = (float) mCurStep/mStepMax;
canvas.drawArc(rectF,135,sweepAngle*270,false,mInnerPaint);
String stepText = mCurStep+"";
//畫文字
Rect bunds = new Rect();
mTextPaint.getTextBounds(stepText,0,stepText.length(),bunds);
int dy = (mTextPaint.getFontMetricsInt().bottom - mTextPaint.getFontMetricsInt().top)/2+mTextPaint.getFontMetricsInt().bottom;
int baseLine = getHeight()/2+dy;
canvas.drawText(stepText,getWidth()/2-bunds.width()/2,baseLine,mTextPaint);
}
這里對(duì)rectF的賦值不太懂的世曾,可以參考這個(gè)鏈接:
關(guān)于canvas.drawArc缨恒,canvas.drawOval 和RectF 的關(guān)系
2.5其他方法
// 寫幾個(gè)方法動(dòng)起來
public synchronized void setStepMax(int stepMax){
this.mStepMax = stepMax;
}
public synchronized void setCurrentStep(int currentStep){
this.mCurStep = currentStep;
// 不斷繪制 onDraw()
invalidate();
}
解釋一下,一個(gè)是設(shè)置你最大運(yùn)動(dòng)的步數(shù)轮听,一個(gè)是設(shè)置你當(dāng)前繪制到的那個(gè)步數(shù)骗露,在此方法中調(diào)用invalidate方法,會(huì)不斷調(diào)用onDraw方法進(jìn)行繪制血巍,這兩個(gè)方法暴露給外部調(diào)用動(dòng)態(tài)改變椒袍。
2.6MainActivity的實(shí)現(xiàn)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final QQStepView qqStepView = (QQStepView) findViewById(R.id.step_view);
qqStepView.setStepMax(4000);
// 屬性動(dòng)畫
ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 3000);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentStep = (float) animation.getAnimatedValue();
qqStepView.setCurrentStep((int)currentStep);
}
});
valueAnimator.start();
}
用屬性動(dòng)畫實(shí)現(xiàn)動(dòng)畫效果
三、結(jié)語
分析完畢藻茂,最后感謝驹暑,darren大神,具有無私分享精神辨赐,帶著一起寫效果优俘,看源碼。
附上代碼地址:http://pan.baidu.com/s/1qXGO4w8