说实话写代码久了,本能的会避免一些不熟悉的领域,而去做一些擅长的领域,这样使工作显得得心应手,但殊不知这是一种逃避行为,只有不断的面临问题甚至主动制造问题,好比说我偏偏不用setVisible这种老旧的显影方式,而是使用去使用动画,不用常用布局堆叠构建UI,而是使用Canvas绘制布局,虽然说到底还是API调用师,笔者不是要歌颂那些勇于尝试的人,只是想多个方法对条路,这也是另一种节约时间成本的方式。
进入正题
国际惯例先上效果图
设计图 | 实现效果 |
---|---|
看完效果会给我打多少分?···
基本样式已出,剩下就是精雕细琢了
按照笔者学习借鉴的套路,一般找几个参考案例,百度,GitHub,谷歌三连,是绝对不会少的
案例一
效果: 指针旋转 + 间隔彩虹
package com.xiaomakj.utillib.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
public class GradualView extends View {
public static final int[] SWEEP_GRADIENT_COLORS = new int[]{Color.GREEN, Color.GREEN, Color.BLUE, Color.RED, Color.RED};
private int tableWidth = 50;
private Paint mPaint;
private Path mPath;
private RectF mTableRectF;
//把路径分成虚线段的
private DashPathEffect dashPathEffect;
//给路径上色
private SweepGradient mColorShader;
//指针的路径
private Path mPointerPath;
private float mCurrentDegree = 60;
public GradualView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPath = new Path();
mPointerPath = new Path();
startAnimator();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
float size = Math.min(w, h) - tableWidth * 2;
//油表的位置方框
mTableRectF = new RectF(0, 0, size, size);
mPath.reset();
//在油表路径中增加一个从起始弧度
mPath.addArc(mTableRectF, 60, 240);
//计算路径的长度
PathMeasure pathMeasure = new PathMeasure(mPath, false);
float length = pathMeasure.getLength();
float step = length / 60;
dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);
float radius = size / 2;
mColorShader = new SweepGradient(radius, radius,SWEEP_GRADIENT_COLORS,null);
//设置指针的路径位置
mPointerPath.reset();
mPointerPath.moveTo(radius, radius - 20);
mPointerPath.lineTo(radius, radius + 20);
mPointerPath.lineTo(radius * 2 - tableWidth, radius);
mPointerPath.close();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float dx = (getWidth() - mTableRectF.width()) / 2;
float dy = (getHeight() - mTableRectF.height()) / 2;
//把油表的方框平移到正中间
canvas.translate(dx, dy);
canvas.save();
//旋转画布
canvas.rotate(90, mTableRectF.width() / 2, mTableRectF.height() / 2);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(tableWidth);
mPaint.setPathEffect(dashPathEffect);
mPaint.setShader(mColorShader);
canvas.drawPath(mPath, mPaint);
canvas.restore();
//还原画笔
mPaint.setPathEffect(null);
mPaint.setShader(null);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(tableWidth / 10);
canvas.save();
canvas.rotate(150 + mCurrentDegree, mTableRectF.width() / 2, mTableRectF.height() / 2);
canvas.drawPath(mPointerPath, mPaint);
canvas.restore();
}
public void startAnimator() {
ValueAnimator animator = ValueAnimator.ofFloat(0, 240);
animator.setDuration(40000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentDegree = (int) (0 + (Float) animation.getAnimatedValue());
invalidate();
}
});
animator.start();
}
}
案例二
效果:彩虹圆弧 + 图形定位
package com.example.yan;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by xiaoyanzi on 2016/3/18.
* 渐变圆弧
*/
public class GradualView extends View {
private Context context;
private Paint paint;//画笔
private Paint paintFull;//实心圆画笔
private Paint textPaint;//标识字画笔
private Paint valuePaint;//移动小球画笔
private int[] mColors;//渐变色数组
private int centerX;//中心X
private int centerY;//中心Y
private int srcH;//控件高度
private float startAngle = 110;//圆弧起始角度
private float sweepAngle = 320;//圆弧所占度数
private float airValue = 66;
/**
* 直接在代码中调用时,使用该函数
*
* @param context
*/
public GradualView(Context context) {
super(context);
initData(context);
}
/**
* 在xml中使用自定义view时,使用这个函数
*
* @param context
* @param attrs
*/
public GradualView(Context context, AttributeSet attrs) {
super(context, attrs);
initData(context);
}
/**
* 可以由上一个函数中手动调用
*
* @param context
* @param atrrs
* @param defStyle 自定义函数中的attrs表示view的属性集,defStyle表示默认的属性资源集的id
*/
public GradualView(Context context, AttributeSet atrrs, int defStyle) {
super(context, atrrs, defStyle);
}
/**
* 初始化
*
* @param context
*/
private void initData(Context context) {
this.context = context;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
mColors = new int[]{
0xFF660099,//紫色
0xFF330033,//褐色
0xFF99FF00,//草绿色
0xFFFFFF00,//黄色
0xFFFF6600,//橘色
0xFFFF0000,//红色
0xFF660099,//紫色
};
Shader s = new SweepGradient(0, 0, mColors, null);
paint.setAntiAlias(true);//设置画笔为无锯齿
paint.setStrokeWidth(dip2px(context, 14));//线宽
paint.setShader(s);
paintFull = new Paint(Paint.ANTI_ALIAS_FLAG);
paintFull.setStyle(Paint.Style.FILL_AND_STROKE);
paintFull.setAntiAlias(true);//设置画笔为无锯齿
paintFull.setShader(s);
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(dip2px(context, 22));//设置字体大小
textPaint.setColor(0xFFFFFFFF);
valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
valuePaint.setAntiAlias(true);//设置画笔为无锯齿
}
public void setAirValue(float airValue) {
this.airValue = airValue;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
srcH = h;
centerX = w / 2;
centerY = h / 2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float r = srcH / 2 - paint.getStrokeWidth() * 0.5f - dip2px(context, 200);
//移动中心
canvas.translate(centerX, centerY);
RectF oval = new RectF();
oval.left = -r;//左边
oval.top = -r;//上边
oval.right = r;//右边
oval.bottom = r;//下边
canvas.drawArc(oval, startAngle, sweepAngle, false, paint); //绘制圆弧
//绘制圆弧两头的小圆
float mr = dip2px(context, 7);
float x1 = (float) (-r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));
float y1 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));
canvas.drawCircle(x1, y1, mr, paintFull);
float x2 = (float) (r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));
float y2 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));
canvas.drawCircle(x2, y2, mr, paintFull);
//小圆离球的距离
float range = r + dip2px(context, 30);
float ar = 12f;
//画周围小球和数字
float ax1 = (float) (-range * Math.sin(45 * Math.PI / 180));
float ay1 = (float) (range * Math.cos(45 * Math.PI / 180));
canvas.drawCircle(ax1, ay1, ar, paintFull);
canvas.drawText("0", ax1 - getTextW() * 3, ay1 + getTextH() / 2, textPaint);
float ax2 = -range;
float ay2 = 0;
canvas.drawCircle(ax2, ay2, ar, paintFull);
canvas.drawText("50", ax2 - getTextW() * 5, ay2 + getTextH() / 2, textPaint);
float ax3 = (float) (-range * Math.sin(45 * Math.PI / 180));
float ay3 = (float) (-range * Math.cos(45 * Math.PI / 180));
canvas.drawCircle(ax3, ay3, ar, paintFull);
canvas.drawText("100", ax3 - getTextW() * 7, ay3 + getTextH() / 2, textPaint);
float ax4 = 0;
float ay4 = -range;
canvas.drawCircle(ax4, ay4, ar, paintFull);
canvas.drawText("150", ax4 - getTextW() * 3, ay4 - getTextH(), textPaint);
float ax5 = (float) (range * Math.sin(45 * Math.PI / 180));
float ay5 = (float) (-range * Math.cos(45 * Math.PI / 180));
canvas.drawCircle(ax5, ay5, ar, paintFull);
canvas.drawText("200", ax5 + getTextW(), ay5 + getTextH() / 2, textPaint);
float ax6 = range;
float ay6 = 0;
canvas.drawCircle(ax6, ay6, ar, paintFull);
canvas.drawText("300", ax6 + getTextW(), ay6 + getTextH() / 2, textPaint);
float ax7 = (float) (range * Math.sin(45 * Math.PI / 180));
float ay7 = (float) (range * Math.cos(45 * Math.PI / 180));
canvas.drawCircle(ax7, ay7, ar, paintFull);
canvas.drawText("500", ax7 + getTextW(), ay7 + getTextH() / 2, textPaint);
//画标识小球
valuePaint.setColor(0xFFFFFFFF);
float cx;
float cy;
if (airValue >= 0 && airValue <= 50) {
cx = (float) (-r * Math.cos((45 - airValue * 0.9) * Math.PI / 180));
cy = (float) (r * Math.sin((45 - airValue * 0.9) * Math.PI / 180));
} else if (airValue > 50 && airValue <= 150) {
cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));
cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));
} else if (airValue > 150 && airValue <= 200) {
cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));
cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));
} else if (airValue > 200 && airValue <= 300) {
cx = (float) (-r * Math.cos((airValue * 0.45 + 45) * Math.PI / 180));
cy = (float) (-r * Math.sin((airValue * 0.45 + 45) * Math.PI / 180));
} else if (airValue > 300 && airValue <= 500) {//此处有问题
cx = (float) (r * Math.cos(((airValue - 300) * 0.225) * Math.PI / 180));
cy = (float) (r * Math.sin(((airValue - 300) * 0.225) * Math.PI / 180));
} else {
cx = (float) (-r * Math.cos(45 * Math.PI / 180));
cy = (float) (r * Math.sin(45 * Math.PI / 180));
}
canvas.drawCircle(cx, cy, dip2px(context, 11), valuePaint);
canvas.drawCircle(cx, cy, dip2px(context, 4), paintFull);
}
/**
* dip转px
*
* @param context
* @param dpValue
* @return
*/
private int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 获取"正"的高度
*
* @return
*/
private float getTextH() {
Paint pFont = new Paint();
Rect rect = new Rect();
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds("正", 0, 1, rect);
return rect.height();
}
/**
* 获取"正"的宽度
*
* @return
*/
private float getTextW() {
Paint pFont = new Paint();
Rect rect = new Rect();
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds("正", 0, 1, rect);
return rect.width();
}
}
最终章:合并大法
效果:效果如上图
package com.xiaomakj.utillib.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
import com.vondear.rxtool.RxTool;
import com.xiaomakj.utillib.R;
/**
* 弧形进度条
*
* @author Vondear
* @date 2015/12/03
*/
public class RxRoundProgress extends View {
private int count;
public static final int STROKE = 0;
/**
* 画笔对象的引用
*/
private Paint paint;
private Path mPath;
private Paint textPaint;
private Paint centerPaint;
private Paint dotPaint;
private Paint dotTexttPaint;
/**
* 圆环的颜色
*/
private int roundColor;
/**
* 圆环进度的颜色
*/
private int roundProgressColor;
/**
* 中间进度百分比的字符串的颜色
*/
private int textColor;
/**
* 中间进度百分比的字符串的字体
*/
private float textSize;
/**
* 圆环的宽度
*/
private float roundWidth;
/**
* 最大进度
*/
private double max;
/**
* 当前进度
*/
private double progress;
/**
* 是否显示中间的进度
*/
private boolean textIsDisplayable;
/**
* 进度的风格,实心或者空心
*/
private int style;
private int centerX;//中心X
private int centerY;//中心Y
private int srcH;//控件高度
public RxRoundProgress(Context context) {
this(context, null);
}
public RxRoundProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RxRoundProgress(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//进度条画笔
paint = new Paint();
mPath = new Path();
//文字画笔
textPaint = new Paint();
//文字画笔
centerPaint = new Paint();
//文字画笔
dotPaint = new Paint();
//文字画笔
dotTexttPaint = new Paint();
TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.RxRoundProgress);
//获取自定义属性和默认值
roundColor = mTypedArray.getColor(R.styleable.RxRoundProgress_roundColor, Color.WHITE);
roundProgressColor = mTypedArray.getColor(R.styleable.RxRoundProgress_roundProgressColor, Color.parseColor("#F6B141"));
textColor = mTypedArray.getColor(R.styleable.RxRoundProgress_textColor, Color.GREEN);
textSize = mTypedArray.getDimension(R.styleable.RxRoundProgress_textSize1, 15);
roundWidth = mTypedArray.getDimension(R.styleable.RxRoundProgress_roundWidth, 20);
max = mTypedArray.getInteger(R.styleable.RxRoundProgress_max, 100);
textIsDisplayable = mTypedArray.getBoolean(R.styleable.RxRoundProgress_textIsDisplayable, true);
style = mTypedArray.getInt(R.styleable.RxRoundProgress_style, 0);
mTypedArray.recycle();
textPaint.setColor(roundColor);
textPaint.setAntiAlias(true);
textPaint.setTextSize(dp2px(13));
dotPaint.setStyle(Paint.Style.STROKE);
dotPaint.setAntiAlias(true);
dotTexttPaint.setStyle(Paint.Style.FILL);
dotTexttPaint.setAntiAlias(true);
dotTexttPaint.setTextSize(dp2px(12));
//中间分数
centerPaint.setColor(textColor);
centerPaint.setAntiAlias(true);
}
int[] mColors = new int[]{
Color.GREEN, 0xFF12B8CA,
Color.RED, Color.RED,
Color.YELLOW, Color.YELLOW,
Color.BLUE, Color.GREEN,
};
/**
* dp转px
*
* @param dpValue dp值
* @return px值
*/
public int dp2px(float dpValue) {
final float scale = RxTool.getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
srcH = h;
centerX = w / 2;
centerY = h / 2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/**
* 画最外层的大圆环
*/
//向右边取启点
//间距
int margin = dp2px(2);
int tPadding = dp2px(40);
//获取圆心的x座标
int center = getWidth() / 2 - tPadding;
//圆环的半径
int radius = (int) (center - roundWidth / 2);
//用于定义的圆弧的形状和大小的界限
RectF innerOval = new RectF(center - radius + tPadding, center - radius + tPadding, center + radius + tPadding, center + radius + tPadding);
int outWidth = dp2px(20);
RectF outOval = new RectF(center - radius + tPadding - outWidth, center - radius + tPadding - outWidth, center + radius + tPadding + outWidth, center + radius + tPadding + outWidth);
//画外圆
mPath.reset();
mPath.addArc(outOval, 135, 270);
//计算路径的长度
PathMeasure pathMeasure = new PathMeasure(mPath, false);
float length = pathMeasure.getLength();
float step = length / 60;
DashPathEffect dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);
SweepGradient mColorShader = new SweepGradient(centerX, centerX, mColors, null);
paint.setPathEffect(dashPathEffect);
//设置彩色
paint.setShader(mColorShader);
//设置空心
paint.setStyle(Paint.Style.STROKE);
//设置圆环的宽度
paint.setStrokeWidth(roundWidth / 2);
//消除锯齿
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawPath(mPath, paint);
//画内圆
mPath.reset();
mPath.addArc(innerOval, 135, 270);
//消除间隔
paint.setPathEffect(null);
paint.setStrokeWidth(roundWidth);
//设置彩色
canvas.drawPath(mPath, paint);
//放弃灰底色圆
// paint.setStrokeCap(Paint.Cap.ROUND);
// paint.setStrokeWidth(roundWidth);
// paint.setColor(roundColor);
// paint.setPathEffect(null);
// //设置彩色
// paint.setShader(null);
//根据进度画圆弧
// canvas.drawArc(innerOval, 135, 270, false, paint);
// canvas.drawRect(0, 0, getWidth(), getWidth(), paint);// 正方形
centerPaint.setTextSize(dp2px(18));
float textH = getTextH(centerPaint, ((int) getProgress()) + "");
canvas.drawText(
((int) getProgress()) + "",
(center + tPadding) - centerPaint.measureText((int) getProgress() + "") / 2,
center + tPadding + textH + radius / 2, centerPaint);
centerPaint.setTextSize(dp2px(14));
float textH2 = getTextH(centerPaint, "平均成绩");
canvas.drawText(
"平均成绩",
(center + tPadding) - centerPaint.measureText("平均成绩") / 2,
center + tPadding + textH + textH2 + margin * 2 + radius / 2, centerPaint);
centerPaint.setTextSize(dp2px(12));
float textH3 = getTextH(centerPaint, "已完成考试" + count + "次");
canvas.drawText(
"已完成考试" + count + "次",
(center + tPadding) - centerPaint.measureText("已完成考试" + count + "次") / 2,
center + tPadding + textH + textH2 + textH3 + margin * 3 + radius / 2, centerPaint);
//左边最小值
// canvas.drawText("0分", (float) (radius - Math.sqrt(2) * (radius / 2) + 10), (float) (2 * radius - Math.sqrt(2) * (radius / 4) + 130), textPaint);
//右边最大值
// canvas.drawText(getMax() + "分", (float) (radius + Math.sqrt(2) * (radius / 2) + 138), (float) (2 * radius - Math.sqrt(2) * (radius / 4) + 130), textPaint);
/*if(progress<50){
double money = progress*1+(Math.floor(Math.random()*getMax()));
canvas.drawText(money+"", (center+toright) - centerPaint.measureText(money+"")/2-15, center+165, centerPaint);//右边最大值
}else{*/
//}
//右边最大值
// canvas.drawText("分", (center + toright) + centerPaint.measureText(RxDataTool.format2Decimals(getProgress() + "")) / 2 - 10, center + 105, dotPaint);
int[] mColors = new int[]{
0xFFFF0000,//红色
0xFFFFFF00,//黄色
0xFF0B74FE,//蓝色
0xFF99FF00//草绿色
};
String[] mStrings = new String[]{
"差",//红色
"中",//黄色
"良",//蓝色
"优"//草绿色
};
for (int i = 0; i < mColors.length; i++) {
dotPaint.setColor(mColors[i]);
dotTexttPaint.setColor(mColors[i]);
canvas.drawCircle(tPadding * 2 / 3 + i / 5f * getWidth(), getHeight() - dp2px(7.5f),
dp2px(5), dotPaint);
canvas.drawText(
mStrings[i],
tPadding * 2 / 3 + i / 5f * getWidth() + getTextW(dotTexttPaint, mStrings[i]) / 2 + margin,
getHeight() - dp2px(10) + getTextH(dotTexttPaint, mStrings[i]) / 2,
dotTexttPaint);
}
// /**
// * 画进度百分比
// */
// paint.setStrokeWidth(0);
// paint.setColor(textColor);
// paint.setTextSize(textSize);
// //设置字体
// paint.setTypeface(Typeface.DEFAULT_BOLD);
// //中间的进度百分比,先转换成float在进行除法运算,不然都为0
// int percent = (int) (((float) progress / (float) max) * 100);
// //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
// float textWidth = paint.measureText(percent + "%");
//
// if (textIsDisplayable && percent != 0 && style == STROKE) {
//// canvas.drawText(percent + "%", center + toright - textWidth / 2, center + toright + textSize / 2, paint); //画出进度百分比
// }
//还原画笔
paint.setPathEffect(null);
paint.setShader(null);
paint.setStyle(Paint.Style.FILL);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pointer);
Rect bitmapRec = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
RectF pointerOval = new RectF(
center + tPadding - bitmap.getWidth() / 2,
center + tPadding - bitmap.getWidth() / 2,
center + tPadding + bitmap.getHeight() / 2,
center + tPadding + bitmap.getHeight() / 2);
Matrix matrix = new Matrix();
matrix.postRotate(-90-45 + 270 * ((float) progress / (float) max), bitmapRec.width() / 2, bitmapRec.height());
matrix.postTranslate(pointerOval.centerX()-bitmap.getWidth()/2, pointerOval.centerY()-bitmap.getHeight());
canvas.drawBitmap(bitmap, matrix, paint);
//canvas.drawBitmap(bitmap, bitmapRec, pointerOval, paint);
/**
* 画圆弧 ,画圆环的进度
*/
//设置进度是实心还是空心
paint.setStrokeWidth(roundWidth); //设置圆环的宽度
paint.setColor(roundProgressColor); //设置进度的颜色
paint.setAntiAlias(true);
switch (style) {
case STROKE: {
paint.setStyle(Paint.Style.STROKE);
if (progress >= 0) {
canvas.drawArc(innerOval, 45, (270 * ((float) progress / (float) max - 1)), false, paint); //根据进度画圆弧
}
break;
}
default:
break;
}
}
public synchronized double getMax() {
return max;
}
/**
* 设置进度的最大值
*
* @param max
*/
public synchronized void setMax(double max) {
if (max < 0) {
throw new IllegalArgumentException("max not less than 0");
}
this.max = max;
}
/**
* 获取进度.需要同步
*
* @return
*/
public synchronized double getProgress() {
return progress;
}
/**
* 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
* 刷新界面调用postInvalidate()能在非UI线程刷新
*
* @param progress
*/
public synchronized void setProgress(double progress) {
if (progress < 0) {
this.progress = progress;
//throw new IllegalArgumentException("progress not less than 0");
}
if (progress > max) {
progress = max;
}
if (progress <= max) {
this.progress = progress;
postInvalidate();
}
}
/**
* 获取"正"的高度
*
* @return
*/
private float getTextH(Paint pFont, String text) {
Rect rect = new Rect();
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds(text, 0, 1, rect);
return rect.height();
}
/**
* 获取"正"的宽度
*
* @return
*/
private float getTextW(Paint pFont, String text) {
Rect rect = new Rect();
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds(text, 0, 1, rect);
return rect.width();
}
public int getCricleColor() {
return roundColor;
}
public void setCricleColor(int cricleColor) {
this.roundColor = cricleColor;
}
public int getCricleProgressColor() {
return roundProgressColor;
}
public void setCricleProgressColor(int cricleProgressColor) {
this.roundProgressColor = cricleProgressColor;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public float getRoundWidth() {
return roundWidth;
}
public void setRoundWidth(float roundWidth) {
this.roundWidth = roundWidth;
}
public int setCount(int count) {
return this.count;
}
}
style
<declare-styleable name="RxRoundProgress">
<attr format="color" name="roundColor"/>
<attr format="color" name="roundProgressColor"/>
<attr format="dimension" name="roundWidth"/>
<attr format="color" name="textColor"/>
<attr format="dimension" name="textSize1"/>
<attr format="integer" name="max"/>
<attr format="boolean" name="textIsDisplayable"/>
<attr name="style">
<enum name="STROKE" value="0"/>
<enum name="FILL" value="1"/>
</attr>
</declare-styleable>
可以看出来笔者自己写的也是二开版本,面向对象不就是只要结果,不讲过程吗?嘿嘿