代码不多,注释也比较详细,全部贴上了:
(一)ProgressBarView1:
代码如下 复制代码
/**
* 自定义绚丽的ProgressBar.
*/
publicclassProgressBarView1extendsView {
/**
* 进度条所占用的角度
*/
privatestaticfinalintARC_FULL_DEGREE =300;
/**
* 弧线的宽度
*/
privateintSTROKE_WIDTH;
/**
* 组件的宽,高
*/
privateintwidth, height;
/**
* 进度条最大值和当前进度值
*/
privatefloatmax, progress;
/**
* 是否允许拖动进度条
*/
privatebooleandraggingEnabled =false;
/**
* 绘制弧线的矩形区域
*/
privateRectF circleRectF;
/**
* 绘制弧线的画笔
*/
privatePaint progressPaint;
/**
* 绘制文字的画笔
*/
privatePaint textPaint;
/**
* 绘制当前进度值的画笔
*/
privatePaint thumbPaint;
/**
* 圆弧的半径
*/
privateintcircleRadius;
/**
* 圆弧圆心位置
*/
privateintcenterX, centerY;
publicProgressBarView1(Context context) {
super(context);
init();
}
publicProgressBarView1(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
publicProgressBarView1(Context context, AttributeSet attrs,intdefStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
privatevoidinit() {
progressPaint =newPaint();
progressPaint.setAntiAlias(true);
textPaint =newPaint();
textPaint.setColor(Color.WHITE);
textPaint.setAntiAlias(true);
thumbPaint =newPaint();
thumbPaint.setAntiAlias(true);
//使用自定义字体
textPaint.setTypeface(Typeface.createFromAsset(getContext().getAssets(),"fangz.ttf"));
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(width ==0|| height ==0) {
width = getWidth();
height = getHeight();
//计算圆弧半径和圆心点
circleRadius = Math.min(width, height) /2;
STROKE_WIDTH = circleRadius /12;
circleRadius -= STROKE_WIDTH;
centerX = width /2;
centerY = height /2;
//圆弧所在矩形区域
circleRectF =newRectF();
circleRectF.left = centerX - circleRadius;
circleRectF.top = centerY - circleRadius;
circleRectF.right = centerX + circleRadius;
circleRectF.bottom = centerY + circleRadius;
}
}
privateRect textBounds =newRect();
@Override
protectedvoidonDraw(Canvas canvas) {
super.onDraw(canvas);
floatstart =90+ ((360- ARC_FULL_DEGREE) >>1);//进度条起始点
floatsweep1 = ARC_FULL_DEGREE * (progress / max);//进度划过的角度
floatsweep2 = ARC_FULL_DEGREE - sweep1;//剩余的角度
//绘制起始位置小圆形
progressPaint.setColor(Color.WHITE);
progressPaint.setStrokeWidth(0);
progressPaint.setStyle(Paint.Style.FILL);
floatradians = (float) (((360.0f - ARC_FULL_DEGREE) /2) /180* Math.PI);
floatstartX = centerX - circleRadius * (float) Math.sin(radians);
floatstartY = centerY + circleRadius * (float) Math.cos(radians);
canvas.drawCircle(startX, startY, STROKE_WIDTH /2, progressPaint);
//绘制进度条
progressPaint.setStrokeWidth(STROKE_WIDTH);
progressPaint.setStyle(Paint.Style.STROKE);//设置空心
canvas.drawArc(circleRectF, start, sweep1,false, progressPaint);
//绘制进度条背景
progressPaint.setColor(Color.parseColor("#d64444"));
canvas.drawArc(circleRectF, start + sweep1, sweep2,false, progressPaint);
//绘制结束位置小圆形
progressPaint.setStrokeWidth(0);
progressPaint.setStyle(Paint.Style.FILL);
floatendX = centerX + circleRadius * (float) Math.sin(radians);
floatendY = centerY + circleRadius * (float) Math.cos(radians);
canvas.drawCircle(endX, endY, STROKE_WIDTH /2, progressPaint);
//上一行文字
textPaint.setTextSize(circleRadius >>1);
String text = (int) (100* progress / max) +"";
floattextLen = textPaint.measureText(text);
//计算文字高度
textPaint.getTextBounds("8",0,1, textBounds);
floath1 = textBounds.height();
//% 前面的数字水平居中,适当调整
floatextra = text.startsWith("1") ? -textPaint.measureText("1") /2:0;
canvas.drawText(text, centerX - textLen /2+ extra, centerY -30+ h1 /2, textPaint);
//百分号
textPaint.setTextSize(circleRadius >>2);
canvas.drawText("%", centerX + textLen /2+ extra +5, centerY -30+ h1 /2, textPaint);
//下一行文字
textPaint.setTextSize(circleRadius /5);
text ="可用内存充足";
textLen = textPaint.measureText(text);
textPaint.getTextBounds(text,0, text.length(), textBounds);
floath2 = textBounds.height();
canvas.drawText(text, centerX - textLen /2, centerY + h1 /2+ h2, textPaint);
//绘制进度位置,也可以直接替换成一张图片
floatprogressRadians = (float) (((360.0f - ARC_FULL_DEGREE) /2+ sweep1) /180* Math.PI);
floatthumbX = centerX - circleRadius * (float) Math.sin(progressRadians);
floatthumbY = centerY + circleRadius * (float) Math.cos(progressRadians);
thumbPaint.setColor(Color.parseColor("#33d64444"));
canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH *2.0f, thumbPaint);
thumbPaint.setColor(Color.parseColor("#99d64444"));
canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH *1.4f, thumbPaint);
thumbPaint.setColor(Color.WHITE);
canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH *0.8f, thumbPaint);
}
privatebooleanisDragging =false;
@Override
publicbooleanonTouchEvent(@NonNullMotionEvent event) {
if(!draggingEnabled) {
returnsuper.onTouchEvent(event);
}
//处理拖动事件
floatcurrentX = event.getX();
floatcurrentY = event.getY();
intaction = event.getAction();
switch(action) {
caseMotionEvent.ACTION_DOWN:
//判断是否在进度条thumb位置
if(checkOnArc(currentX, currentY)) {
floatnewProgress = calDegreeByPosition(currentX, currentY) / ARC_FULL_DEGREE * max;
setProgressSync(newProgress);
isDragging =true;
}
break;
caseMotionEvent.ACTION_MOVE:
if(isDragging) {
//判断拖动时是否移出去了
if(checkOnArc(currentX, currentY)) {
setProgressSync(calDegreeByPosition(currentX, currentY) / ARC_FULL_DEGREE * max);
}else{
isDragging =false;
}
}
break;
caseMotionEvent.ACTION_UP:
isDragging =false;
break;
}
returntrue;
}
privatefloatcalDistance(floatx1,floaty1,floatx2,floaty2) {
return(float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
/**
* 判断该点是否在弧线上(附近)
*/
privatebooleancheckOnArc(floatcurrentX,floatcurrentY) {
floatdistance = calDistance(currentX, currentY, centerX, centerY);
floatdegree = calDegreeByPosition(currentX, currentY);
returndistance > circleRadius - STROKE_WIDTH *5&& distance < circleRadius + STROKE_WIDTH *5
&& (degree >= -8&& degree <= ARC_FULL_DEGREE +8);
}
/**
* 根据当前位置,计算出进度条已经转过的角度。
*/
privatefloatcalDegreeByPosition(floatcurrentX,floatcurrentY) {
floata1 = (float) (Math.atan(1.0f * (centerX - currentX) / (currentY - centerY)) / Math.PI *180);
if(currentY < centerY) {
a1 +=180;
}elseif(currentY > centerY && currentX > centerX) {
a1 +=360;
}
returna1 - (360- ARC_FULL_DEGREE) /2;
}
publicvoidsetMax(intmax) {
this.max = max;
invalidate();
}
publicvoidsetProgress(floatprogress) {
finalfloatvalidProgress = checkProgress(progress);
//动画切换进度值
newThread(newRunnable() {
@Override
publicvoidrun() {
floatoldProgress = ProgressBarView1.this.progress;
for(inti =1; i <=100; i++) {
ProgressBarView1.this.progress = oldProgress + (validProgress - oldProgress) * (1.0f * i /100);
postInvalidate();
SystemClock.sleep(20);
}
}
}).start();
}
publicvoidsetProgressSync(floatprogress) {
this.progress = checkProgress(progress);
invalidate();
}
//保证progress的值位于[0,max]
privatefloatcheckProgress(floatprogress) {
if(progress <0) {
return0;
}
returnprogress > max ? max : progress;
}
publicvoidsetDraggingEnabled(booleandraggingEnabled) {
this.draggingEnabled = draggingEnabled;
}
}
(二)ProgressBarView2:
代码如下 复制代码
/**
* 自定义绚丽的ProgressBar.
*/
publicclassProgressBarView2extendsView {
/**
* 进度条所占用的角度
*/
privatestaticfinalintARC_FULL_DEGREE =300;
//进度条个数
privatestaticfinalintCOUNT =100;
//每个进度条所占用角度
privatestaticfinalfloatARC_EACH_PROGRESS = ARC_FULL_DEGREE *1.0f / (COUNT -1);
/**
* 弧线细线条的长度
*/
privateintARC_LINE_LENGTH;
/**
* 弧线细线条的宽度
*/
privateintARC_LINE_WIDTH;
/**
* 组件的宽,高
*/
privateintwidth, height;
/**
* 进度条最大值和当前进度值
*/
privatefloatmax, progress;
/**
* 绘制弧线的画笔
*/
privatePaint progressPaint;
/**
* 绘制文字的画笔
*/
privatePaint textPaint;
/**
* 绘制文字背景圆形的画笔
*/
privatePaint textBgPaint;
/**
* 圆弧的半径
*/
privateintcircleRadius;
/**
* 圆弧圆心位置
*/
privateintcenterX, centerY;
publicProgressBarView2(Context context) {
super(context);
init();
}
publicProgressBarView2(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
publicProgressBarView2(Context context, AttributeSet attrs,intdefStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
privatevoidinit() {
progressPaint =newPaint();
progressPaint.setAntiAlias(true);
textPaint =newPaint();
textPaint.setColor(Color.WHITE);
textPaint.setAntiAlias(true);
textBgPaint =newPaint();
textBgPaint.setAntiAlias(true);
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(width ==0|| height ==0) {
width = getWidth();
height = getHeight();
//计算圆弧半径和圆心点
circleRadius = Math.min(width, height) /2;
ARC_LINE_LENGTH = circleRadius /6;
ARC_LINE_WIDTH = ARC_LINE_LENGTH /8;
centerX = width /2;
centerY = height /2;
}
}
privateRect textBounds =newRect();
@Override
protectedvoidonDraw(Canvas canvas) {
super.onDraw(canvas);
floatstart = (360- ARC_FULL_DEGREE) >>1;//进度条起始角度
floatsweep1 = ARC_FULL_DEGREE * (progress / max);//进度划过的角度
//绘制进度条
progressPaint.setColor(Color.parseColor(calColor(progress / max,"#ffff0000","#ff00ff00")));
progressPaint.setStrokeWidth(ARC_LINE_WIDTH);
floatdrawDegree =1.6f;
while(drawDegree <= ARC_FULL_DEGREE) {
doublea = (start + drawDegree) /180* Math.PI;
floatlineStartX = centerX - circleRadius * (float) Math.sin(a);
floatlineStartY = centerY + circleRadius * (float) Math.cos(a);
floatlineStopX = lineStartX + ARC_LINE_LENGTH * (float) Math.sin(a);
floatlineStopY = lineStartY - ARC_LINE_LENGTH * (float) Math.cos(a);
if(drawDegree > sweep1) {
//绘制进度条背景
progressPaint.setColor(Color.parseColor("#88aaaaaa"));
progressPaint.setStrokeWidth(ARC_LINE_WIDTH >>1);
}
canvas.drawLine(lineStartX, lineStartY, lineStopX, lineStopY, progressPaint);
drawDegree += ARC_EACH_PROGRESS;
}
//绘制文字背景圆形
textBgPaint.setStyle(Paint.Style.FILL);//设置填充
textBgPaint.setColor(Color.parseColor("#41668b"));
canvas.drawCircle(centerX, centerY, (circleRadius - ARC_LINE_LENGTH) *0.8f, textBgPaint);
textBgPaint.setStyle(Paint.Style.STROKE);//设置空心
textBgPaint.setStrokeWidth(2);
textBgPaint.setColor(Color.parseColor("#aaaaaaaa"));
canvas.drawCircle(centerX, centerY, (circleRadius - ARC_LINE_LENGTH) *0.8f, textBgPaint);
//上一行文字
textPaint.setTextSize(circleRadius >>1);
String text = (int) (100* progress / max) +"";
floattextLen = textPaint.measureText(text);
//计算文字高度
textPaint.getTextBounds("8",0,1, textBounds);
floath1 = textBounds.height();
canvas.drawText(text, centerX - textLen /2, centerY - circleRadius /10+ h1 /2, textPaint);
//分
textPaint.setTextSize(circleRadius >>3);
textPaint.getTextBounds("分",0,1, textBounds);
floath11 = textBounds.height();
canvas.drawText("分", centerX + textLen /2+5, centerY - circleRadius /10+ h1 /2- (h1 - h11), textPaint);
//下一行文字
textPaint.setTextSize(circleRadius /6);
text ="点击优化";
textLen = textPaint.measureText(text);
canvas.drawText(text, centerX - textLen /2, centerY + circleRadius /2.5f, textPaint);
}
publicvoidsetMax(intmax) {
this.max = max;
invalidate();
}
//动画切换进度值(异步)
publicvoidsetProgress(finalfloatprogress) {
newThread(newRunnable() {
@Override
publicvoidrun() {
floatoldProgress = ProgressBarView2.this.progress;
for(inti =1; i <=100; i++) {
ProgressBarView2.this.progress = oldProgress + (progress - oldProgress) * (1.0f * i /100);
postInvalidate();
SystemClock.sleep(20);
}
}
}).start();
}
//直接设置进度值(同步)
publicvoidsetProgressSync(floatprogress) {
this.progress = progress;
invalidate();
}
/**
* 计算渐变效果中间的某个颜色值。
* 仅支持 #aarrggbb 模式,例如 #ccc9c9b2
*/
publicString calColor(floatfraction, String startValue, String endValue) {
intstart_a, start_r, start_g, start_b;
intend_a, end_r, end_g, end_b;
//start
start_a = getIntValue(startValue,1,3);
start_r = getIntValue(startValue,3,5);
start_g = getIntValue(startValue,5,7);
start_b = getIntValue(startValue,7,9);
//end
end_a = getIntValue(endValue,1,3);
end_r = getIntValue(endValue,3,5);
end_g = getIntValue(endValue,5,7);
end_b = getIntValue(endValue,7,9);
return"#"+ getHexString((int) (start_a + fraction * (end_a - start_a)))
+ getHexString((int) (start_r + fraction * (end_r - start_r)))
+ getHexString((int) (start_g + fraction * (end_g - start_g)))
+ getHexString((int) (start_b + fraction * (end_b - start_b)));
}
//从原始#AARRGGBB颜色值中指定位置截取,并转为int.
privateintgetIntValue(String hexValue,intstart,intend) {
returnInteger.parseInt(hexValue.substring(start, end),16);
}
privateString getHexString(intvalue) {
String a = Integer.toHexString(value);
if(a.length() ==1) {
a ="0"+ a;
}
returna;
}
}
没有了