您的位置:首页 > 其它

从一个简洁的进度刻度绘制中了解自定义View的思路流程

2016-07-28 10:13 706 查看


先看效果(原谅我的渣像素),进度的刻度、宽度、颜色可以随意设定:



【项目github地址: https://github.com/zhangke3016/CircleLoading

实现起来并不难,通过本文,我们可以学到:


1、自定义属性的使用。

2、shader的使用

3、自定义View中对onmeasure的处理

4、增深对PathMeasure工具类的了解

5、最主要的是对自定义View有个比较清晰的思路认识



一、原理介绍

做这样一个进度效果,我们可以拆分如下步骤来实现:


1、从外部圆环开始测量绘制;

2、再加入刻度条效果;

3、再加入刻度随进度增加而增加效果;

4、增加自定义属性增加可定制性;

5、控件使用方法介绍



【zhangke3016 http://blog.csdn.net/zhangke3016

OK,有了这个思路,那我们开始吧:

1、测量绘制外部圆环

首先我们要开始绘制外部的圆环,这步很简单,主要是使用canvas的drawArc()方法,

/*
* @param oval 画弧线矩形区域
* @param startAngle 开始的角度
* @param sweepAngle 划过的角度
* @param useCenter 如果为true 为实心圆弧
* @param paint     画笔
* /
public void drawArc(RectF oval, float startAngle, float sweepAngle,boolean useCenter,Paint paint)


这个相对简单,主要是确定开始角度,并不断增加绘制划过角度,圆弧就出现在界面中了,这里需要注意的是RectF oval的大小确定:

在确定RectF oval之前,我们要先测量确定当前控件的宽高,根据当前控件的宽高来确定oval的合适大小。

测量当前控件的大小一般我们在onmeasure()方法中处理,resolveMeasured()方法传递两个参数,第一各参数为widthMeasureSpec或者heightMeasureSpec,第二个参数为期望值也就是默认值。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(resolveMeasured(widthMeasureSpec, nDesired), resolveMeasured(heightMeasureSpec, nDesired));
}

/**
*
* @param measureSpec
* @param desired
* @return
*/
private int resolveMeasured(int measureSpec, int desired)
{
int result = 0;
int specSize = MeasureSpec.getSize(measureSpec);
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.UNSPECIFIED: //
result = desired;
break;
case MeasureSpec.AT_MOST:  //wrap-content
result = Math.min(specSize, desired);
break;
case MeasureSpec.EXACTLY:  //match-content
default:
result = specSize;
}
return result;
}


在测量之后我们就可以来求oval的具体大小 ,我把这步操作放在了onSizeChanged方法中,求出最小一边的一半减去圆环的宽度,得到圆弧的半径,然后根据半径以控件中心为中心绘制我们所需要的矩形区域。

radiu = (int) ((Math.min(getWidth(), getHeight()))/2-mPaint.getStrokeWidth());

oval.left = getWidth()/2-radiu;
oval.top = getHeight()/2-radiu;
oval.right = getWidth()/2+radiu;
oval.bottom = getHeight()/2+radiu;


这样下来,基本上就可以绘制比较理想的弧线了,在这里也把绘制中心文字也说下吧,主要通过getTextBounds()方法获取文字区域的宽高,然后在drawText()方法中将坐标进行适当偏移以使文字居中显示。

String strProgressText = "";
if(mOnProgressListener !=null){//如果不为空  则为接口返回的值
strProgressText = mOnProgressListener.OnProgress(mMax, mProgress);
}else{
strProgressText = mProgress+"/"+mMax;
}
mTextPaint.getTextBounds(strProgressText, 0, strProgressText.length(), bounds);
canvas.drawText(strProgressText, oval.centerX()-bounds.width()/2, oval.centerY()+bounds.height()/2, mTextPaint);


最后还有一个小点就是渐变色的绘制,用的SweepGradient,我们可以看下Shader的子类,shader类是很强大的,类似与圆形图片、渐变效果都可以用它来实现,这里就不过多展开了:



SweepGradient sweepGradient = new SweepGradient(getWidth()/2, getHeight()/2, colors, null);
p.setShader(sweepGradient);


到这里为止,我们的圆环已经绘制好了,包括中间的文字以及圆环的渐变效果都已经实现了,就是这样的:



2、加入刻度效果

接下来要加入刻度效果,实现思路是这样的,我先默认实现两个圆弧(注意这两个圆弧只是我们假定添加的,并不是真正加在控件中显示),然后获取相同角度,根据相对位置获取两个圆环上的点进行连线,将这两个点连起的刻度线封装成对象添加在集合中,最后在onDraw方法中遍历集合,进行绘制。


oval2 = new RectF();//内环
oval2.left = getWidth()/2-radiu/4f*3;
oval2.top = getHeight()/2-radiu/4f*3;
oval2.right = getWidth()/2+radiu/4f*3;
oval2.bottom = getHeight()/2+radiu/4f*3;

oval3 = new RectF();//外环
oval3.left = getWidth()/2-radiu/8f*7;
oval3.top = getHeight()/2-radiu/8f*7;
oval3.right = getWidth()/2+radiu/8f*7;
oval3.bottom = getHeight()/2+radiu/8f*7;

//然后初始化数据
/**
* 初始化数据
*/
private void initData() {
mLinesList.clear();

Path path = new Path();
Path path1 = new Path();
//从startAngle开始 绘制180角度
path.addArc(oval2, mStartAngle, mGraduationSweepAngle);
path1.addArc(oval3, mStartAngle, mGraduationSweepAngle);

PathMeasure pm = new PathMeasure(path, false);
float itemLength = pm.getLength()/(nGraduationCount-1);

PathMeasure pm1 = new PathMeasure(path1, false);

float[] pos = new float[2];
float[] postemp = new float[2];
for (int i = 0; i < nGraduationCount; i++) {
pm.getPosTan(itemLength*i, pos , null );
pm1.getPosTan(itemLength*i/pm.getLength()*pm1.getLength(), postemp , null);
Line line = new Line();
line.p1.x = pos[0];
line.p1.y = pos[1];
line.p2.x = postemp[0];
line.p2.y = postemp[1];
mLinesList.add(line);
}
}

//ondraw方法:
for (int i = 0; i < mLinesList.size(); i++) {
Line line = mLinesList.get(i);
canvas.drawLine(line.p1.x, line.p1.y, line.p2.x, line.p2.y, mRollPaint);
}


这里用到了PathMeasure这个辅助工具,这里简单讲一下:

public PathMeasure()

//path:需要测量的path  forceClosed:是否关闭path
public PathMeasure(Path path, boolean forceClosed)

//指定需要测量的path
public void setPath(Path path, boolean forceClosed)

//返回当前path的总长度。
getLength()

//返回值是boolean,如过path为空,则返回false 传入参数有三个:
//distance:传入距离起点的距离。
//pos[]:意思是position,分别对应点的x,y坐标
//tan[]:获取切线值,不常用。
public boolean getPosTan(float distance, float pos[], float tan[])

//返回一个处理好的matrix,但是这个matrix是以左上角作为旋转点,所以需要将这个点移动到中心点。 其中一个参数flags,指这个martrix需要什么信息。flags的值有如下两个
PathMeasure.POSITION_MATRIX_FLAG:位置信息
pathMeasure.TANGENT_MATRIX_FLAG:切边信息,方位角信息
public boolean getMatrix(float distance, Matrix matrix, int flags)

//这个方法返回boolean,如果截取的长度为0则返回false,否则为true。参数如下
//startD:起始距离
//stopD:终点距离
//dst:接收截取的path
//startWithMoveTo:是否把截取的path,moveto到起始点。
public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)


3、加入刻度随进度增加而增加效果,并增加进度变化回调方便操作

加入刻度随进度增加而增加,我们可以这样想,首先我总的刻度数是一定的,判断划过的角度占圆周的百分比,随之就可以得到划过刻度数占总刻度数的百分比,进而就求出划过的刻度数了。

for (int i = 0; i < Math.round(mSweepAngle*nGraduationCount/360f); i++) {
if(i<mLinesList.size()){
Line line = mLinesList.get(i);
canvas.drawLine(line.p1.x, line.p1.y, line.p2.x, line.p2.y, mRollDrawPaint);
}
}


将划过的刻度数用画笔再绘制一次,随进度增加的刻度效果就出现啦!

/**
* 设置进度监听
* @param mOnProgressListener
*/
public void setOnProgressListener(OnProgressListener mOnProgressListener) {
this.mOnProgressListener = mOnProgressListener;
}
/**
* 用于外部判断当前进度状态
*/
interface OnProgressListener{
/**
* 返回中间部分文字内容
* @param max
* @param progress
* @return
*/
String OnProgress(int max,int progress);
}


设置回调监听,这样在每次进度变化的时候,可以随意变化中间部分文字显示的内容。

4、增加自定义属性增加可定制性

attrs.xml:

<declare-styleable name="LoadingStyle">
<attr name="textSize" format="dimension|reference"/><!-- 字体大小 -->
<attr name="textColor" format="color|reference"/><!-- 字体颜色 -->
<attr name="strokeWidth" format="dimension|reference"/><!-- 圆环大小 -->
<attr name="isShowGraduationBackground" format="boolean"/><!-- 是否显示背景刻度 -->
<attr name="isShowOutRoll" format="boolean"/><!-- 是否显示外部进度框 -->
<attr name="startAngle" format="integer|reference"/><!-- 开始的角度 -->
<attr name="max" format="integer|reference"/><!-- 最大值 -->
<attr name="progress" format="integer|reference"/><!-- 默认进度值 -->
<attr name="graduationBackgroundColor" format="color|reference"/><!-- 刻度的背景颜色 -->
<attr name="graduationWidth" format="dimension|reference"/><!-- 刻度的宽度 -->
<attr name="graduationCount" format="integer|reference"/><!-- 刻度的个数 -->
</declare-styleable>


layout文件:

xmlns:app="http://schemas.android.com/apk/res-auto"<!--设置命名空间 -->

<com.mrzk.circleloadinglibrary.CircleLoadingView
android:id="@+id/lv_loading"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
app:textSize="35sp"
app:textColor="#f60"
app:strokeWidth="10dp"
app:isShowGraduationBackground="true"
app:startAngle="0"
app:max="300"
app:progress="100"
app:graduationBackgroundColor="#ccc"
app:graduationWidth="5dp"
app:graduationCount="10"
app:isShowOutRoll="false"
/>


获取自定义属性值:

TypedArray typedArray = getResources().obtainAttributes(attrs, R.styleable.LoadingStyle);
mTextSize = (int) typedArray.getDimension(R.styleable.LoadingStyle_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));
mStrokeWidth = (int) typedArray.getDimension(R.styleable.LoadingStyle_strokeWidth, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()));
mGraduationWidth = (int) typedArray.getDimension(R.styleable.LoadingStyle_graduationWidth, mStrokeWidth/2);
mTextColor = (int) typedArray.getColor(R.styleable.LoadingStyle_textColor, Color.BLACK);
mGraduationBackgroundColor = (int) typedArray.getColor(R.styleable.LoadingStyle_graduationBackgroundColor, Color.BLACK);
mStartAngle = (int) typedArray.getInt(R.styleable.LoadingStyle_startAngle, 180);
mMax = (int) typedArray.getInt(R.styleable.LoadingStyle_max, 0);
mProgress = (int) typedArray.getInt(R.styleable.LoadingStyle_progress, 0);
nGraduationCount = (int) typedArray.getInt(R.styleable.LoadingStyle_graduationCount, 35);
isShowGraduationBackground =  typedArray.getBoolean(R.styleable.LoadingStyle_isShowGraduationBackground, true);
isShowOutRoll =  typedArray.getBoolean(R.styleable.LoadingStyle_isShowOutRoll, true);
typedArray.recycle();


5、使用方法

int[] colors = {0xFFE5BD7D, 0xFFFAAA64,
0xFFFFFFFF, 0xFF6AE2FD,
0xFF8CD0E5, 0xFFA3CBCB,
0xFFBDC7B3, 0xFFD1C299, 0xFFE5BD7D};
lv_loading.setTextColor(Color.BLACK);//设置中心文字颜色
lv_loading.setMax(500);//设置最大进度
lv_loading.setShowGraduationBackgroundEnable(true);//是否显示刻度背景
lv_loading.setGraduationBackgroundColor(Color.GRAY);//刻度的背景颜色
lv_loading.setStartAngle(180);//设置开始旋转角度
lv_loading.setGraduationCount(10);//设置刻度数
lv_loading.setGraduationWidth(5);//设置刻度的宽度
lv_loading.setOutColors(colors);//设置外部圆环颜色
lv_loading.setInnerGraduationColors(colors);//设置内部刻度进度颜色
lv_loading.setTextSize(35);//设置内部文字字体大小
lv_loading.setShowOutRollEnable(false);//设置是否显示外部进度框
lv_loading.setOnProgressListener(new OnProgressListener() {
@Override
public String OnProgress(int max, int progress) {

return progress*100f/max+"%";
}
});




二、源码附上

/**
* 进度视图
* @author zhang
*
*/
public class CircleLoadingView extends View{
/** 圆环的画笔 */
private Paint mPaint;
/** 文字的画笔 */
private Paint mTextPaint;
/** 刻度的画笔 */
private Paint mRollPaint;
//进度刻度的画笔
private Paint mRollDrawPaint;
/** 圆环的宽度 */
private int mStrokeWidth = 0;
/** 字体的大小 */
private int mTextSize = 0;
/** 字体的颜色 */
private int mTextColor = 0;
/** 圆环所在区域 */
private RectF oval;
private Rect bounds;//获取文字的宽高 使文字居中
private float mStartAngle = 180;//开始的角度
private float mSweepAngle = 0;//划过的角度
/** 刻度的背景色 */
private int mGraduationBackgroundColor = Color.BLACK;
/** 刻度的宽度 */
private int mGraduationWidth = 0;
private float mGraduationSweepAngle = 359.9f;//刻度划过的角度 如果为360度 获取刻度会默认从右边划过
private int mMax = 0;//设置的最大值
private int mProgress = 0;//设置的进度
//分段颜色 外环
private int[] OUT_SECTION_COLORS = {
0xFFE5BD7D, 0xFFFAAA64,
0xFFFFFFFF, 0xFF6AE2FD,
0xFF8CD0E5, 0xFFA3CBCB,
0xFFBDC7B3, 0xFFD1C299,
0xFFE5BD7D};
//内部刻度
private int[] INNER_SECTION_COLORS = {
0xFFE5BD7D, 0xFFFAAA64,
0xFFFFFFFF, 0xFF6AE2FD,
0xFF8CD0E5, 0xFFA3CBCB,
0xFFBDC7B3, 0xFFD1C299,
0xFFE5BD7D};
/** 宽高的默认值 */
private int nDesired = 0;
private RectF oval2;//临时的内圆
private RectF oval3;//临时的外圆
/** 刻度的个数 */
private int nGraduationCount = 35;
/** 所有线的集合 */
private List<Line> mLinesList = new ArrayList<LoadingView.Line>();
/** 进度监听器 */
private OnProgressListener mOnProgressListener;
/**
* 是否显示进度条的背景 默认为
* @see #setShowGraduationBackgroundEnable(boolean)
* */
private boolean isShowGraduationBackground = true;
/**
* 是否显示外部进度框
* @see #setShowOutRollEnable(boolean)
* */
private boolean isShowOutRoll = true;
public CircleLoadingView(Context context) {
this(context,null);
}
public CircleLoadingView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CircleLoadingView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray typedArray = getResources().obtainAttributes(attrs, R.styleable.LoadingStyle); mTextSize = (int) typedArray.getDimension(R.styleable.LoadingStyle_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics())); mStrokeWidth = (int) typedArray.getDimension(R.styleable.LoadingStyle_strokeWidth, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics())); mGraduationWidth = (int) typedArray.getDimension(R.styleable.LoadingStyle_graduationWidth, mStrokeWidth/2); mTextColor = (int) typedArray.getColor(R.styleable.LoadingStyle_textColor, Color.BLACK); mGraduationBackgroundColor = (int) typedArray.getColor(R.styleable.LoadingStyle_graduationBackgroundColor, Color.BLACK); mStartAngle = (int) typedArray.getInt(R.styleable.LoadingStyle_startAngle, 180); mMax = (int) typedArray.getInt(R.styleable.LoadingStyle_max, 0); mProgress = (int) typedArray.getInt(R.styleable.LoadingStyle_progress, 0); nGraduationCount = (int) typedArray.getInt(R.styleable.LoadingStyle_graduationCount, 35); isShowGraduationBackground = typedArray.getBoolean(R.styleable.LoadingStyle_isShowGraduationBackground, true); isShowOutRoll = typedArray.getBoolean(R.styleable.LoadingStyle_isShowOutRoll, true); typedArray.recycle();
init();
}
/**
* 设置进度监听
* @param mOnProgressListener
*/
public void setOnProgressListener(OnProgressListener mOnProgressListener) {
this.mOnProgressListener = mOnProgressListener;
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//消除锯齿
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(0xFF0099CC);
mPaint.setStrokeWidth(mStrokeWidth);
mPaint.setStrokeCap(Paint.Cap.ROUND);

mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setColor(mTextColor);
mTextPaint.setFakeBoldText(true);//设置字体加粗
mTextPaint.setTextSize(mTextSize);

mRollPaint = new Paint(mPaint);
mRollPaint.setColor(mGraduationBackgroundColor);
// mRollPaint.setStrokeWidth(mStrokeWidth/2);
mRollPaint.setStrokeWidth(mGraduationWidth);

mRollDrawPaint = new Paint(mPaint);
mRollDrawPaint.setStrokeWidth(mGraduationWidth);

oval = new RectF();
bounds = new Rect();

nDesired = dip2px(60);
}
/**
* 初始化数据
*/
private void initData() {
mLinesList.clear();

Path path = new Path();
Path path1 = new Path();
//从startAngle开始 绘制180角度
path.addArc(oval2, mStartAngle, mGraduationSweepAngle);
path1.addArc(oval3, mStartAngle, mGraduationSweepAngle);

PathMeasure pm = new PathMeasure(path, false);
float itemLength = pm.getLength()/(nGraduationCount-1);

PathMeasure pm1 = new PathMeasure(path1, false);

float[] pos = new float[2];
float[] postemp = new float[2];
for (int i = 0; i < nGraduationCount; i++) {
pm.getPosTan(itemLength*i, pos , null );
pm1.getPosTan(itemLength*i/pm.getLength()*pm1.getLength(), postemp , null);
Line line = new Line();
line.p1.x = pos[0];
line.p1.y = pos[1];
line.p2.x = postemp[0];
line.p2.y = postemp[1];
mLinesList.add(line);
}
}

public int dip2px(int dip){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(resolveMeasured(widthMeasureSpec, nDesired), resolveMeasured(heightMeasureSpec, nDesired));
}
/**
* 设置渐变颜色
*/
private void setSweepShader(int[] colors,Paint p) {
SweepGradient sweepGradient = new SweepGradient(getWidth()/2, getHeight()/2, colors, null); p.setShader(sweepGradient);
}
/** 设置层叠颜色 */
public void setOutColors(int[] colors){
OUT_SECTION_COLORS = colors;
setSweepShader(OUT_SECTION_COLORS,mPaint);
}
/** 设置层叠颜色 */
public void setInnerGraduationColors(int[] colors){
INNER_SECTION_COLORS = colors;
setSweepShader(INNER_SECTION_COLORS,mRollDrawPaint);
}
/**
*
* @param measureSpec
* @param desired
* @return
*/
private int resolveMeasured(int measureSpec, int desired)
{
int result = 0;
int specSize = MeasureSpec.getSize(measureSpec);
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.UNSPECIFIED: //
result = desired;
break;
case MeasureSpec.AT_MOST: //wrap
result = Math.min(specSize, desired);
break;
case MeasureSpec.EXACTLY: //match
default:
result = specSize;
}
return result;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int radiu = 0;
if(oval.bottom<=0){
radiu = (int) ((Math.min(getWidth(), getHeight()))/2-mPaint.getStrokeWidth()); oval.left = getWidth()/2-radiu; oval.top = getHeight()/2-radiu; oval.right = getWidth()/2+radiu; oval.bottom = getHeight()/2+radiu;

oval2 = new RectF();
oval2.left = getWidth()/2-radiu/4f*3;
oval2.top = getHeight()/2-radiu/4f*3;
oval2.right = getWidth()/2+radiu/4f*3;
oval2.bottom = getHeight()/2+radiu/4f*3;

oval3 = new RectF();
oval3.left = getWidth()/2-radiu/8f*7;
oval3.top = getHeight()/2-radiu/8f*7;
oval3.right = getWidth()/2+radiu/8f*7;
oval3.bottom = getHeight()/2+radiu/8f*7;
}
//初始化数据
initData();
//设置渐变色
setSweepShader(OUT_SECTION_COLORS,mPaint);
setSweepShader(INNER_SECTION_COLORS,mRollDrawPaint);
}
@Override
protected void onDraw(Canvas canvas) {
if(isShowOutRoll){
canvas.drawArc(oval, mStartAngle, mSweepAngle, false, mPaint);
}else{
canvas.drawArc(oval, mStartAngle, 360, false, mPaint);
}

if(isShowGraduationBackground){
for (int i = 0; i < mLinesList.size(); i++) {
Line line = mLinesList.get(i);
canvas.drawLine(line.p1.x, line.p1.y, line.p2.x, line.p2.y, mRollPaint);
}
}

// int degree = (int) (Math.round(mGraduationSweepAngle)/ITEMCOUNT);
// for (int i = 0; i < Math.round(mSweepAngle/degree); i++) {
for (int i = 0; i < Math.round(mSweepAngle*nGraduationCount/360f); i++) { if(i<mLinesList.size()){ Line line = mLinesList.get(i); canvas.drawLine(line.p1.x, line.p1.y, line.p2.x, line.p2.y, mRollDrawPaint); } }
String strProgressText = ""; if(mOnProgressListener !=null){//如果不为空 则为接口返回的值 strProgressText = mOnProgressListener.OnProgress(mMax, mProgress); }else{ strProgressText = mProgress+"/"+mMax; } mTextPaint.getTextBounds(strProgressText, 0, strProgressText.length(), bounds); canvas.drawText(strProgressText, oval.centerX()-bounds.width()/2, oval.centerY()+bounds.height()/2, mTextPaint);
}

/**
* 设置是否显示外部进度条
* @param isShowOutRoll
*/
public void setShowOutRollEnable(boolean isShowOutRoll){
this.isShowOutRoll = isShowOutRoll;
}
/**
* 设置是否显示进度条的背景
* @param isShowGraduationBackground
*/
public void setShowGraduationBackgroundEnable(boolean isShowGraduationBackground){
this.isShowGraduationBackground = isShowGraduationBackground;
}
/**
* 设置显示进度数量
* @param nGraduationCount
*/
public void setGraduationCount(int nGraduationCount){
this.nGraduationCount = nGraduationCount;
}
/**
* 设置进度的背景颜色
* @param mGraduationBackgroundColor
*/
public void setGraduationBackgroundColor(int mGraduationBackgroundColor){
this.mGraduationBackgroundColor = mGraduationBackgroundColor;
mRollPaint.setColor(mGraduationBackgroundColor);
}
/**
* 设置刻度的宽度
* @param mGraduationWidth
*/
public void setGraduationWidth(int mGraduationWidth){
this.mGraduationWidth = mGraduationWidth;
mRollPaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mGraduationWidth, getResources().getDisplayMetrics()));
mRollDrawPaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mGraduationWidth, getResources().getDisplayMetrics()));
}

/**
* 设置最大进度值
* @param max
*/
public void setMax(int max){
this.mMax = max;
}
/**
* 设置进度
* @param progress
*/
public void setProgress(int progress){
this.mProgress = progress;
if(mMax==0){
throw new IllegalArgumentException("Max不能为0!");
}
mSweepAngle = 360f*mProgress/mMax;
postInvalidate();
}
/**
* 设置开始的角度 可以控制开始的位置 默认为180 即从左边开始
* @param mStartAngle
*/
public void setStartAngle(float mStartAngle){
this.mStartAngle = mStartAngle;
}

/**
* 设置字体颜色
* @param mTextColor
*/
public void setTextColor(int mTextColor){
this.mTextColor = mTextColor;
mTextPaint.setColor(mTextColor);
}
/**
* 设置字体大小
* @param mTextSize
*/
public void setTextSize(int mTextSize){
this.mTextSize = mTextSize;
mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, getResources().getDisplayMetrics()));
}
/**
* 用于外部判断当前进度状态
*/
interface OnProgressListener{
/**
* 返回中间部分文字内容
* @param max
* @param progress
* @return
*/
String OnProgress(int max,int progress);
}
/**
* 刻度对象
*/
class Line{
PointF p1 = new PointF();
PointF p2 = new PointF();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: