1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > android 第三方圆弧进度条 Android 圆弧进度条 水平进度条 水波进度条

android 第三方圆弧进度条 Android 圆弧进度条 水平进度条 水波进度条

时间:2024-07-01 13:34:36

相关推荐

android 第三方圆弧进度条 Android 圆弧进度条  水平进度条  水波进度条

先上效果图:

loading.gif

以下代码直接复制即可使用, 碰到类似样式的, 可以根据自己需求修改.

①. 在arrts.xml添加对应属性.

②. 把源码复制过去即可使用.

1. 圆弧进度条 ArcProgressView

ArcProgressView.png

属性:

//中间文字

//文字大小

//文字颜色

//进度条 内层颜色

//进度条 外层颜色

//进度条 内层大小

//进度条 外层大小

//开始角度

//绘制角度,默认360, 例如:180时为一个半圆

使用: 其它View使用方式一样

android:id="@+id/arc_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="200dp"

app:liys_progress_arc_inCircleColor="#EDEDED"

app:liys_progress_arc_textSize="15dp"

app:liys_progress_arc_text="0%"/>

2. 线性进度条 LineTextProgressView

LineTextProgressView.png

属性:

//文字

//文字大小

//文字颜色

//进度条 内层大小

//进度条 外层大小

//进度条 内层颜色

//进度条 外层颜色

3. 水平进度条(带文字) HorzTextProgressView

HorzTextProgressView.png

属性

//文字

//文字大小

//文字颜色

//进度条 内层大小

//进度条 外层大小

//进度条 内层颜色

//进度条 外层颜色

4. 水平进度条(不带文字) HorzProgressView

HorzProgressView.png

属性:

//最大值

//当前进度值

//进度条 外层大小

//进度条 内层颜色

//进度条 外层颜色

//进度条 内层图片(可选)

//进度条 外层图片(可选)

5. 水波 进度条 WaterWaveProView

WaterWaveProView.png

属性:

//中间文字内容

//文字大小

//文字颜色

//内层颜色

//外层颜色

>>>>>>>>>>>>>>>>>>>>>>>>附上源码>>>>>>>>>>>>>>>>>>>>>>>>>>>>

/**

* 圆弧进度条

* @author liys 401654546@

* @version 1.0 /09/12

*/

public class ArcProgressView extends View {

private double mMaxNum = 10000; //最大值

private double mCurrentNum = 0; //当前的值

private String mText = "0%"; //当前 百分比

private int mTextSize; //字体大小

private int mTextColor = 0; //字体颜色

private int mInColor = 0; //内圈颜色

private int mOutColor = 0; //外圈颜色

private int mInCircleSize; //外圈大小 单位sp

private int mOutCircleSize; //内圈大小 单位sp

private int mStartAngle; //开始角度

private int mDrawAngle; //需要绘制的角度

private int mCurrentAngle = 0; //当前角度

private int mWidth; //宽

private int mHeight; //高

int defaultWidth = 100; //默认宽高,单位sp

//画笔

private Paint mTextPaint;

private Paint mInPaint;

private Paint mOutPaint;

public ArcProgressView(Context context) {

this(context, null, 0);

}

public ArcProgressView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public ArcProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//默认值

int defaultTextSize = 20; //默认字体大小

int defaultCircleSize = 10; //默认圆弧大小 单位sp

int defaultStartAngle = -90; //默认开始角度

int defaultDrawAngle = 360; //默认绘制角度

String defaultTextColor = "#ABC4DF"; //默认字体颜色

String defaultInColor = "#EDEDED"; //默认内颜色

String defaultOutColor = "#CCBD00"; //默认外颜色

// 获取自定义属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcProgressView);

mText = typedArray.getString(R.styleable.ArcProgressView_liys_progress_arc_text);

mTextSize = typedArray.getDimensionPixelSize(R.styleable.ArcProgressView_liys_progress_arc_textSize, sp2px(defaultTextSize));

mStartAngle = typedArray.getInt(R.styleable.ArcProgressView_liys_progress_arc_startAngle, defaultStartAngle);

mDrawAngle = typedArray.getInt(R.styleable.ArcProgressView_liys_progress_arc_drawAngle, defaultDrawAngle);

mTextColor = typedArray.getColor(R.styleable.ArcProgressView_liys_progress_arc_textColor, Color.parseColor(defaultTextColor));

mInColor = typedArray.getColor(R.styleable.ArcProgressView_liys_progress_arc_inCircleColor, Color.parseColor(defaultInColor));

mOutColor = typedArray.getColor(R.styleable.ArcProgressView_liys_progress_arc_outCircleColor, Color.parseColor(defaultOutColor));

mInCircleSize = typedArray.getDimensionPixelSize(R.styleable.ArcProgressView_liys_progress_arc_inCircleSize, sp2px(defaultCircleSize));

mOutCircleSize = typedArray.getDimensionPixelSize(R.styleable.ArcProgressView_liys_progress_arc_outCircleSize, sp2px(defaultCircleSize));

typedArray.recycle();

//设置画笔

mTextPaint = new Paint();

mInPaint = new Paint();

mOutPaint = new Paint();

setTextPaint();

setInPaint();

setOutPaint();

}

/**

* 文字画笔

*/

private void setTextPaint() {

mTextPaint.setColor(mTextColor);

mTextPaint.setAntiAlias(true);

mTextPaint.setTextSize(mTextSize);

}

/**

* 内圆弧画笔

*/

private void setInPaint() {

mInPaint.setColor(mInColor);

mInPaint.setAntiAlias(true);

mInPaint.setStrokeWidth(mInCircleSize); //大小

mInPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

mInPaint.setStyle(Paint.Style.STROKE); //空心样式

}

/**

* 外圆弧画笔

*/

private void setOutPaint() {

mOutPaint.setColor(mOutColor);

mOutPaint.setAntiAlias(true);

mOutPaint.setStrokeWidth(mOutCircleSize); //大小

mOutPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

mOutPaint.setStyle(Paint.Style.STROKE); //空心样式

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//取默认值

mWidth = sp2px(defaultWidth);

mHeight = sp2px(defaultWidth);

//1. 获取宽

if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mWidth = MeasureSpec.getSize(widthMeasureSpec);

}

//2.获取高

if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mHeight = MeasureSpec.getSize(heightMeasureSpec);

}

//3. 确定宽高(保持宽高一致)

mWidth = mHeight = (mWidth > mHeight ? mHeight : mWidth);

setMeasuredDimension(mWidth, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

drawText(canvas);

drawInCircle(canvas);

drawOutCircle(canvas);

}

//内圆弧

private void drawInCircle(Canvas canvas) {

int r = mInCircleSize / 2; //圆弧的一半

RectF rectF = new RectF(r, r, mWidth - r, mHeight - r);

canvas.drawArc(rectF, mStartAngle, mDrawAngle, false, mInPaint);

}

//内圆弧

private void drawOutCircle(Canvas canvas) {

int r = mOutCircleSize / 2; //圆弧的一半

RectF rectF = new RectF(r, r, mWidth - r, mHeight - r);

if (mCurrentAngle > mDrawAngle) {

mCurrentAngle = mDrawAngle;

}

canvas.drawArc(rectF, mStartAngle, mCurrentAngle, false, mOutPaint);

}

private void drawText(Canvas canvas) {

//1. 获取绘制字体区域

Rect bounds = new Rect();

mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);

//2.获取准线

Paint.FontMetricsInt metrics = mTextPaint.getFontMetricsInt();

int dy = (metrics.bottom - metrics.top) / 2 - metrics.bottom;

int baseLine = mHeight / 2 + dy;

//3.绘制文字

canvas.drawText(mText, mWidth / 2 - bounds.width() / 2, baseLine, mTextPaint);

}

private int sp2px(int sp) {

return (int) TypedValue.applyDimension(PLEX_UNIT_SP, sp,

getResources().getDisplayMetrics());

}

public void setMaxNum(double maxNum) {

this.mMaxNum = maxNum;

}

public void setCurrentNum(double currentNum) {

this.mCurrentNum = currentNum;

//计算角度 mCurrentStep/mMaxStep = mCurrentAngle/mDrawAngle;

mCurrentAngle = (int)(currentNum * mDrawAngle / mMaxNum);

mText = new DecimalFormat("0.00%").format(mCurrentNum/mMaxNum);

invalidate();

}

}

/**

* 线性进度条

* @author liys 401654546@

* @version 1.0 /09/12

*/

public class LineTextProgressView extends View{

private double mMaxNum = 10000; //最大值

private double mCurrentNum = 0; //当前的值

private String mText = "0%"; //当前 百分比

private int mTextSize; //字体大小

private int mTextColor = 0; //字体颜色

private int mInLineColor = 0; //内线颜色

private int mOutLineColor = 0; //外线颜色

private int mInLineSize; //外线 大小 单位sp

private int mOutLineSize; //内线 大小 单位sp

private int mWidth; //宽

private int mHeight; //高

int mDefaultWidth = 300; //默认宽,单位sp

int mDefaultHeight = 30; //默认高,单位sp

int mTriangleValue = 8;

//画笔

private Paint mTextPaint;

private Paint mInPaint;

private Paint mOutPaint;

private Paint mBoxPaint;

public LineTextProgressView(Context context) {

this(context, null);

}

public LineTextProgressView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public LineTextProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//默认值

int defaultTextSize = 10; //默认字体大小 单位sp

String defaultTextColor = "#FFFFFF"; //默认字体颜色

String defaultInColor = "#EDEDED"; //默认内颜色

String defaultOutColor = "#CCBD00"; //默认外颜色

int defaultLineSize = 10; //默认线的大小 单位sp

// 获取自定义属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LineTextProgressView);

mText = typedArray.getString(R.styleable.LineTextProgressView_liys_progress_line_text);

mTextColor = typedArray.getColor(R.styleable.LineTextProgressView_liys_progress_line_textColor, Color.parseColor(defaultTextColor));

mInLineColor = typedArray.getColor(R.styleable.LineTextProgressView_liys_progress_line_inLineColor, Color.parseColor(defaultInColor));

mOutLineColor = typedArray.getColor(R.styleable.LineTextProgressView_liys_progress_line_outLineColor, Color.parseColor(defaultOutColor));

mTextSize = typedArray.getDimensionPixelSize(R.styleable.LineTextProgressView_liys_progress_line_textSize, sp2px(defaultTextSize));

mInLineSize = typedArray.getDimensionPixelSize(R.styleable.LineTextProgressView_liys_progress_line_inLineSize, sp2px(defaultLineSize));

mOutLineSize = typedArray.getDimensionPixelSize(R.styleable.LineTextProgressView_liys_progress_line_outLineSize, sp2px(defaultLineSize));

typedArray.recycle();

setTextPaint();

setInPaint();

setOutPaint();

setBoxPaint();

if(mText == null){

mText = "00.00%";

}

}

/**

* 方框画笔

*/

private void setBoxPaint() {

mBoxPaint = new Paint();

mBoxPaint.setAntiAlias(true);

mBoxPaint.setColor(mOutLineColor);

}

/**

* 文字画笔

*/

private void setTextPaint() {

mTextPaint = new Paint();

mTextPaint.setAntiAlias(true);

mTextPaint.setColor(mTextColor);

mTextPaint.setTextSize(mTextSize);

}

/**

* 内线画笔

*/

private void setInPaint() {

mInPaint = new Paint();

mInPaint.setAntiAlias(true);

mInPaint.setColor(mInLineColor);

mInPaint.setStrokeWidth(mInLineSize); //大小

mInPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

/**

* 外线画笔

*/

private void setOutPaint() {

mOutPaint = new Paint();

mOutPaint.setAntiAlias(true);

mOutPaint.setColor(mOutLineColor);

mOutPaint.setStrokeWidth(mOutLineSize); //大小

mOutPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//取默认值

mWidth = sp2px(mDefaultWidth);

mHeight = sp2px(mDefaultHeight);

//1. 获取宽

if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mWidth = MeasureSpec.getSize(widthMeasureSpec);

}

//2.获取高

if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mHeight = MeasureSpec.getSize(heightMeasureSpec);

}

//2. 确定宽高

setMeasuredDimension(mWidth, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//1 确定文字外框区域

Rect bounds = new Rect();

String str = "100.00%";

mTextPaint.getTextBounds(str, 0, str.length(), bounds);

int boxWidth = bounds.width() + sp2px(5);

int boxHeight = bounds.height() + sp2px(10);

int outWidth = (int)(mCurrentNum/mMaxNum * (mWidth-boxWidth)); //计算当前进度距离

drawBox(canvas, outWidth, boxWidth, boxHeight); //绘制外框

//2 画文字

Paint.FontMetricsInt metrics = mTextPaint.getFontMetricsInt();

int dy = (metrics.bottom - metrics.top) / 2 - metrics.bottom;

int baseLine = boxHeight / 2 + dy; //基线

//文字变化的时候 为了保证文字居中 所以需要知道文字区域大小

Rect bound = new Rect();

mTextPaint.getTextBounds(mText, 0, mText.length(), bound); //获取文字区域大小

canvas.drawText(mText, outWidth + (boxWidth/2 - bound.width()/2), baseLine, mTextPaint);

//3. 画进度条

//方式一:推荐

drawHLine(canvas, boxWidth/2, (boxHeight+sp2px(mTriangleValue)),mWidth, mHeight, mInPaint); //画内线

drawHLine(canvas, boxWidth/2, (boxHeight+sp2px(mTriangleValue)),boxWidth/2 + outWidth, mHeight, mOutPaint); //画外线

//方式一:不推荐

// int lineHeight = mHeight-boxHeight-sp2px(mTriangleValue);

// drawInLine(canvas, boxWidth/2, mWidth - boxWidth/2, lineHeight, mInPaint); //画内线

// drawOutLine(canvas, boxWidth/2, boxWidth/2 + outWidth, lineHeight, mOutPaint); //画外线

}

/**

* @param canvas

* @param left 左边距离

* @param width 矩形 宽

* @param height 矩形 高

*/

public void drawBox(Canvas canvas, int left, int width, int height){

//2.1 画圆角矩形

RectF rectF = new RectF(left, 0, width + left, height);// 设置个新的长方形

canvas.drawRoundRect(rectF, height/4, height/4, mBoxPaint);//第二个参数是x半径,第三个参数是y半径

//2.2 画三角形 (绘制这个三角形,你可以绘制任意多边形)

Path path = new Path();

path.moveTo(left + width/2-sp2px(4), height);// 此点为多边形的起点

path.lineTo(left + width/2+sp2px(4), height);

path.lineTo(left + width/2, height + sp2px(5));

path.close(); // 使这些点构成封闭的多边形

canvas.drawPath(path, mBoxPaint);

}

/**

* 水平进度条(前进方向平的) 通用

* @param canvas

* @param left

* @param top

* @param right

* @param bottom

* @param paint

*/

public void drawHLine(Canvas canvas, int left, int top, int right, int bottom, Paint paint){

int height = bottom - top; //高度

int r = height/2; //半径

int cFirstX = left + r; //第一个分割点x坐标

int cSecondX = mWidth - left - r; //第二个分割点x坐标

int cy = top + r; //圆心y坐标

//1. 绘制第一个圆

canvas.save();

canvas.clipRect(new RectF(left, top, right, bottom));

canvas.drawCircle(left+r, cy, r, paint);

canvas.restore();

//2. 绘制中间矩形

if(right >= cFirstX){

canvas.save();

int currentRight = right;

if(right > cSecondX){

currentRight = cSecondX;

}

canvas.drawRect(new RectF(left+r, top, currentRight, bottom), paint);

canvas.restore();

}

//3. 绘制最后的圆

if(right >= cSecondX){

canvas.save();

canvas.clipRect(new RectF(cSecondX, top, right, bottom));

canvas.drawCircle(cSecondX, cy, r, paint);

canvas.restore();

}

}

public void drawInLine(Canvas canvas, int left, int width, int height, Paint paint){

RectF rectF = new RectF(left, mHeight-height, width, mHeight); // 设置个新的长方形

canvas.drawRoundRect(rectF, height/2, height/2, paint); //第二个参数是x半径,第三个参数是y半径

}

//进度前进方向为圆角

public void drawOutLine(Canvas canvas, int left, int width, int height, Paint paint){

if((width-left) >= height){ //绘制圆角方式

RectF rectF = new RectF(left, mHeight-height, width, mHeight); // 设置个新的长方形

canvas.drawRoundRect(rectF, height/2, height/2, paint); //第二个参数是x半径,第三个参数是y半径

}

//绘制前面圆

RectF rectF = new RectF(left, mHeight-height, width, mHeight);

canvas.clipRect(rectF);

int r = height/2;

canvas.drawCircle(left+r, mHeight-height+r, r, paint);

}

private int sp2px(int sp) {

return (int) TypedValue.applyDimension(PLEX_UNIT_SP, sp,

getResources().getDisplayMetrics());

}

public void setCurrentNum(double currentNum) {

this.mCurrentNum = currentNum;

if(mCurrentNum > mMaxNum){

mCurrentNum = mMaxNum;

}

mText = new DecimalFormat("0.00%").format(mCurrentNum/mMaxNum);

invalidate();

}

}

/**

* 水平进度条(带文字)

* @author liys 401654546@

* @version 1.0 /09/12

*/

public class HorzTextProgressView extends View{

private double mMaxNum = 10000; //最大值

private double mCurrentNum = 0; //当前的值

private String mText = "0%"; //当前 百分比

private int mTextSize; //字体大小

private int mTextColor = 0; //字体颜色

private int mInLineColor = 0; //内线颜色

private int mOutLineColor = 0; //外线颜色

private int mInLineSize; //外线 大小 单位sp

private int mOutLineSize; //内线 大小 单位sp

private int mWidth; //宽

private int mHeight; //高

private int mDefaultWidth = 300; //默认宽,单位sp

private int mDefaultHeight = 20; //默认高,单位sp

int boxWidth = 30; //文字框 宽 单位sp

//画笔

private Paint mTextPaint;

private Paint mInPaint;

private Paint mOutPaint;

private Paint mBoxPaint;

public HorzTextProgressView(Context context) {

this(context, null);

}

public HorzTextProgressView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public HorzTextProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//默认值

int defaultTextSize = 10; //默认字体大小 单位sp

String defaultTextColor = "#FFFFFF"; //默认字体颜色

String defaultInColor = "#EDEDED"; //默认内颜色

String defaultOutColor = "#CCBD00"; //默认外颜色

int defaultLineSize = 10; //默认线的大小 单位sp

// 获取自定义属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HorzTextProgressView);

mText = typedArray.getString(R.styleable.HorzTextProgressView_liys_progress_horz_text);

mTextColor = typedArray.getColor(R.styleable.HorzTextProgressView_liys_progress_horz_textColor, Color.parseColor(defaultTextColor));

mInLineColor = typedArray.getColor(R.styleable.HorzTextProgressView_liys_progress_horz_inLineColor, Color.parseColor(defaultInColor));

mOutLineColor = typedArray.getColor(R.styleable.HorzTextProgressView_liys_progress_horz_outLineColor, Color.parseColor(defaultOutColor));

mTextSize = typedArray.getDimensionPixelSize(R.styleable.HorzTextProgressView_liys_progress_horz_textSize, sp2px(defaultTextSize));

mInLineSize = typedArray.getDimensionPixelSize(R.styleable.HorzTextProgressView_liys_progress_horz_inLineSize, sp2px(defaultLineSize));

mOutLineSize = typedArray.getDimensionPixelSize(R.styleable.HorzTextProgressView_liys_progress_horz_outLineSize, sp2px(defaultLineSize));

typedArray.recycle();

setTextPaint();

setInPaint();

setOutPaint();

setBoxPaint();

if(mText == null){

mText = "0%";

}

boxWidth = sp2px(boxWidth);

}

/**

* 方框画笔

*/

private void setBoxPaint() {

mBoxPaint = new Paint();

mBoxPaint.setAntiAlias(true);

mBoxPaint.setColor(mOutLineColor);

}

/**

* 文字画笔

*/

private void setTextPaint() {

mTextPaint = new Paint();

mTextPaint.setAntiAlias(true);

mTextPaint.setColor(mTextColor);

mTextPaint.setTextSize(mTextSize);

}

/**

* 内线画笔

*/

private void setInPaint() {

mInPaint = new Paint();

mInPaint.setAntiAlias(true);

mInPaint.setColor(mInLineColor);

mInPaint.setStrokeWidth(mInLineSize); //大小

mInPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

/**

* 外线画笔

*/

private void setOutPaint() {

mOutPaint = new Paint();

mOutPaint.setAntiAlias(true);

mOutPaint.setColor(mOutLineColor);

mOutPaint.setStrokeWidth(mOutLineSize); //大小

mOutPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//取默认值

mWidth = sp2px(mDefaultWidth);

mHeight = sp2px(mDefaultHeight);

//1. 获取宽

if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mWidth = MeasureSpec.getSize(widthMeasureSpec);

}

//2.获取高

if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mHeight = MeasureSpec.getSize(heightMeasureSpec);

}

//2. 确定宽高

setMeasuredDimension(mWidth, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//1. 获取当前进度

int outWidth = (int)(mCurrentNum/mMaxNum * mWidth); //计算当前进度距离

if(outWidth >= mWidth - boxWidth){

outWidth = (mWidth - boxWidth);

}

//2. 画进度条

int inTop = (mHeight - mInLineSize)/2;

int outTop = (mHeight - mOutLineSize)/2;

drawHLine(canvas, 0, inTop, mWidth, mHeight - inTop, mInPaint); //画内线

drawHLine(canvas, 0, outTop, outWidth+sp2px(2), mHeight - outTop, mOutPaint); //画外线

//3. 画文字框

drawBox(canvas, outWidth, boxWidth, mHeight);

//4. 画文字

Paint.FontMetricsInt metrics = mTextPaint.getFontMetricsInt();

int dy = (metrics.bottom - metrics.top) / 2 - metrics.bottom;

int baseLine = mHeight/2 + dy; //基线

//文字变化的时候 为了保证文字居中 所以需要知道文字区域大小

Rect bound = new Rect();

mTextPaint.getTextBounds(mText, 0, mText.length(), bound); //获取文字区域大小

canvas.drawText(mText, outWidth + (boxWidth/2 - bound.width()/2), baseLine, mTextPaint);

}

/**

* @param canvas

* @param left 左边距离

* @param width 矩形 宽

* @param height 矩形 高

*/

public void drawBox(Canvas canvas, int left, int width, int height){

RectF rectF = new RectF(left, 0, width + left, height); // 设置个新的长方形

canvas.drawRoundRect(rectF, height/2, height/2, mBoxPaint); //第二个参数是x半径,第三个参数是y半径

}

/**

* 水平进度条(前进方向平的) 通用

* @param canvas

* @param left

* @param top

* @param right

* @param bottom

* @param paint

*/

public void drawHLine(Canvas canvas, int left, int top, int right, int bottom, Paint paint){

int height = bottom - top; //高度

int r = height/2; //半径

int cFirstX = left + r; //第一个分割点x坐标

int cSecondX = mWidth - left - r; //第二个分割点x坐标

int cy = top + r; //圆心y坐标

//1. 绘制第一个圆

canvas.save();

canvas.clipRect(new RectF(left, top, right, bottom));

canvas.drawCircle(left+r, cy, r, paint);

canvas.restore();

//2. 绘制中间矩形

if(right >= cFirstX){

canvas.save();

int currentRight = right;

if(right > cSecondX){

currentRight = cSecondX;

}

canvas.drawRect(new RectF(left+r, top, currentRight, bottom), paint);

canvas.restore();

}

//3. 绘制最后的圆

if(right >= cSecondX){

canvas.save();

canvas.clipRect(new RectF(cSecondX, top, right, bottom));

canvas.drawCircle(cSecondX, cy, r, paint);

canvas.restore();

}

}

private int sp2px(int sp) {

return (int) TypedValue.applyDimension(PLEX_UNIT_SP, sp,

getResources().getDisplayMetrics());

}

public void setCurrentNum(double currentNum) {

this.mCurrentNum = currentNum;

if(mCurrentNum > mMaxNum){

mCurrentNum = mMaxNum;

}

mText = new DecimalFormat("0%").format(mCurrentNum/mMaxNum);

invalidate();

}

}

**

* liys -01-13

* 水平进度条(不带文字)

*/

public class HorzProgressView extends View{

private double mMaxNum = 100; //最大值

private double mCurrentNum = 0; //当前的值

private int mInLineColor = 0; //内线颜色

private int mOutLineColor = 0; //外线颜色

private Drawable mInLineDrawable = null; //内线图片

private Drawable mOutLineDrawable = null; //外线图片

private int mOutLineSize; //外线 大小 单位sp

private int mWidth; //宽

private int mHeight; //高

//画笔

private Paint mInPaint;

private Paint mOutPaint;

private Paint mPaint = new Paint(); //绘制图片

public HorzProgressView(Context context) {

this(context, null);

}

public HorzProgressView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public HorzProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

// 获取自定义属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HorzProgressView);

mCurrentNum = typedArray.getInteger(R.styleable.HorzProgressView_liys_progress_line_progress, 0);

mMaxNum = typedArray.getInteger(R.styleable.HorzProgressView_liys_progress_line_max, 100);

//颜色

mInLineColor = typedArray.getColor(R.styleable.HorzProgressView_liys_progress_line_inColor, 0);

mOutLineColor = typedArray.getColor(R.styleable.HorzProgressView_liys_progress_line_outColor, 0);

//图片

mInLineDrawable = typedArray.getDrawable(R.styleable.HorzProgressView_liys_progress_line_inDrawable);

mOutLineDrawable = typedArray.getDrawable(R.styleable.HorzProgressView_liys_progress_line_outDrawable);

//大小

mOutLineSize = typedArray.getDimensionPixelSize(R.styleable.HorzProgressView_liys_progress_line_outSize, 0);

typedArray.recycle();

setInPaint();

setOutPaint();

}

/**

* 内线画笔

*/

private void setInPaint() {

mInPaint = new Paint();

mInPaint.setAntiAlias(true);

mInPaint.setColor(mInLineColor);

mInPaint.setStrokeWidth(mHeight); //大小

mInPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

/**

* 外线画笔

*/

private void setOutPaint() {

mOutPaint = new Paint();

mOutPaint.setAntiAlias(true);

mOutPaint.setColor(mOutLineColor);

mOutPaint.setStrokeWidth(mOutLineSize); //大小

mOutPaint.setStrokeCap(Paint.Cap.ROUND); // 结束位置圆角

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//1. 获取宽

if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mWidth = MeasureSpec.getSize(widthMeasureSpec);

}

//2.获取高

if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mHeight = MeasureSpec.getSize(heightMeasureSpec);

}

if(mOutLineSize == 0){

mOutLineSize = mHeight;

}

//2. 确定宽高

setMeasuredDimension(mWidth, mHeight);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//内层

if(mInLineColor != 0){

drawInLine(canvas, 0, mWidth, mHeight, mInPaint); //画内线

}

if(mInLineDrawable != null){

Bitmap bitmap = ((BitmapDrawable) mInLineDrawable).getBitmap();

canvas.drawBitmap(bitmap, null, new Rect(0,0, mWidth, mHeight), mPaint);

}

//外层

int left = (mHeight-mOutLineSize)/2;

int width = (int)((mWidth-left)*(mCurrentNum/mMaxNum));

if(mOutLineColor != 0){

drawOutLine(canvas, left, width, mOutLineSize, mOutPaint); //画外线

}

if(mOutLineDrawable != null){

Bitmap bitmap = ((BitmapDrawable) mOutLineDrawable).getBitmap();

canvas.drawBitmap(bitmap, null, new Rect(left,(mHeight-mOutLineSize)/2, width, mOutLineSize), mPaint);

}

}

public void drawInLine(Canvas canvas, int left, int width, int height, Paint paint){

RectF rectF = new RectF(left, mHeight-height, width, mHeight); // 设置个新的长方形

canvas.drawRoundRect(rectF, height/2, height/2, paint); //第二个参数是x半径,第三个参数是y半径

}

/**

* 进度前进方向为圆角

*/

public void drawOutLine(Canvas canvas, int left, int width, int height, Paint paint){

int top = (mHeight-height)/2;

if((width-left) >= height){ //绘制圆角方式

// RectF rectF = new RectF(left, mHeight-height, width, mHeight); // 设置个新的长方形

RectF rectF = new RectF(left, top, width, mHeight-top); // 设置个新的长方形

canvas.drawRoundRect(rectF, height/2, height/2, paint); //第二个参数是x半径,第三个参数是y半径

}

//绘制前面圆

RectF rectF = new RectF(left, top, width, mHeight-top);

canvas.clipRect(rectF);

int r = height/2;

canvas.drawCircle(left+r, top+r, r, paint);

}

public void setMax(double max){

this.mMaxNum = max;

invalidate();

}

public void setCurrentNum(double currentNum) {

this.mCurrentNum = currentNum;

if(mCurrentNum > mMaxNum){

mCurrentNum = mMaxNum;

}

invalidate();

}

}

/**

* 水波进度条

* @author liys 401654546@

* @version 1.0 /09/12

*/

public class WaterWaveProView extends View {

private double mMaxNum = 10000; //最大值

private double mCurrentNum = 0; //当前的值

private double mPercent = 0.0; //百分比

private String mText = ""; //当前 百分比

private int mTextSize; //字体大小

private int mTextColor; //字体大小

private int mInColor = 0; //里面颜色

private int mWaterColor = 0; //水波颜色

//控件宽高

private int mWidth;

private int mHeight;

int mDefaultWidthHeight= 100; //默认宽高,单位sp

private float mStartX = 0; //开始位置

private int mWaveWidth; //水波长

private int mWaveHeight; //水波高度

private Paint mPaint;

private Paint mTextPaint;

private Path mPath;

public WaterWaveProView(Context context) {

this(context, null);

}

public WaterWaveProView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public WaterWaveProView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setLayerType(View.LAYER_TYPE_SOFTWARE, null);//关闭硬件加速

//默认值

int defaultTextSize = 20; //默认字体大小 单位sp

String defaultTextColor = "#FFFFFF"; //默认字体颜色

String defaultInColor = "#69B655"; //默认里面颜色

String defaultWaterColor = "#0AA328"; //默认水波颜色

// 获取自定义属性

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaterWaveProView);

mText = typedArray.getString(R.styleable.WaterWaveProView_liys_progress_water_text);

mTextSize = typedArray.getDimensionPixelSize(R.styleable.WaterWaveProView_liys_progress_water_textSize, sp2px(defaultTextSize));

mTextColor = typedArray.getColor(R.styleable.WaterWaveProView_liys_progress_water_textColor, Color.parseColor(defaultTextColor));

mWaterColor = typedArray.getColor(R.styleable.WaterWaveProView_liys_progress_water_waterColor, Color.parseColor(defaultInColor));

mInColor = typedArray.getColor(R.styleable.WaterWaveProView_liys_progress_water_inColor, Color.parseColor(defaultWaterColor));

typedArray.recycle();

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setColor(mWaterColor);

mTextPaint = new Paint();

mTextPaint.setAntiAlias(true);

mTextPaint.setColor(mTextColor);

mTextPaint.setTextSize(mTextSize);

mPath = new Path();

if(mText == null){

mText = "0.00%";

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int defaultWaterHeight = 5; //默认水波高度 单位sp

//1.取默认宽高

mWidth = sp2px(mDefaultWidthHeight);

mHeight = sp2px(mDefaultWidthHeight);

//2. 获取宽

if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mWidth = MeasureSpec.getSize(widthMeasureSpec);

}

//3.获取高

if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { //具体值

mHeight = MeasureSpec.getSize(heightMeasureSpec);

}

//4. 确定宽高(保持宽高一致)

mWidth = mHeight = (mWidth > mHeight ? mHeight : mWidth);

//5. 确定波长和波高

mWaveWidth = mWidth/4;

mWaveHeight = sp2px(defaultWaterHeight);

setMeasuredDimension(mWidth, mHeight);

start();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//1. 绘制贝塞尔曲线

drawBessel(mWidth, mStartX, (int)(mHeight*(1-mPercent)), mWaveWidth, mWaveHeight, mPath, mPaint);

canvas.drawPath(mPath, mPaint);

//2. 设置模式

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));

//3. 绘制圆形bitmap

canvas.drawBitmap(createCircleBitmap(mWidth/2, mInColor), null, new Rect(0,0,mWidth,mHeight), mPaint);

//4. 绘制文字

drawText(canvas, mText, mWidth, mHeight, mTextPaint);

}

/**

* 绘制贝塞尔曲线

* @param width 总共需要绘制的长度

* @param startX 开始X点坐标(-2*startX 到 0 之间) 左右预留一个波长

* @param startY 开始Y坐标

* @param waveWidth 波长(半个周期)

* @param waveHeight 波高

* @param path

* @param paint 画笔

*/

private void drawBessel(float width, float startX, float startY, float waveWidth, float waveHeight, Path path, Paint paint){

//Android贝塞尔曲线

// 二阶写法:rQuadTo(float dx1, float dy1, float dx2, float dy2) 相对上一个起点的坐标

path.reset();

int currentWidth = 0; //当前已经绘制的宽度

path.moveTo(startX,startY); //画笔位置

while (currentWidth <= width + 4*waveWidth && waveWidth>0){

path.rQuadTo(waveWidth, -waveHeight, 2*waveWidth, 0);

path.rQuadTo(waveWidth, waveHeight, 2*waveWidth, 0);

currentWidth += 2*waveWidth;

}

//封闭的区域

mPath.lineTo(getWidth()+4*waveWidth,getHeight());

mPath.lineTo(0,getHeight());

path.close();

}

private Bitmap createCircleBitmap(int radius, int color){

Bitmap canvasBmp = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(canvasBmp);

canvas.drawColor(Color.TRANSPARENT);

Paint paint = new Paint();

paint.setColor(color);

canvas.drawCircle(radius, radius, radius, paint); //确定位置

return canvasBmp;

}

/**

* 绘制文字 居中

* @param canvas

* @param text 文字内容

* @param width 绘制区域 宽

* @param height 绘制区域 高

* @param paint

*/

public void drawText(Canvas canvas, String text, int width, int height, Paint paint){

Rect bounds = new Rect();

paint.getTextBounds(text,0, mText.length(), bounds);

Paint.FontMetricsInt metrics = paint.getFontMetricsInt();

int dy = (metrics.bottom - metrics.top) / 2 - metrics.bottom;

int baseLine = height / 2 + dy; //基线

canvas.drawText(text, width/2-bounds.width()/2, baseLine, paint);

}

/**

* 设置当前进度

* @param currentNum

*/

public void setCurrentNum(double currentNum) {

this.mCurrentNum = currentNum;

setPercent();

}

public void setMaxNum(int maxNum){

this.mMaxNum = maxNum;

setPercent();

}

private void setPercent(){

if(mCurrentNum > mMaxNum){

mCurrentNum = mMaxNum;

}

mPercent = mCurrentNum/mMaxNum;

mText = new DecimalFormat("0.00%").format(mPercent);

}

private void setStartX(float startX){

mStartX = startX;

invalidate();

}

private int sp2px(int sp) {

return (int) TypedValue.applyDimension(PLEX_UNIT_SP, sp,

getResources().getDisplayMetrics());

}

private void start(){

ValueAnimator animator = ValueAnimator.ofFloat(0-4*mWaveWidth, 0);

animator.setInterpolator(new LinearInterpolator());//匀速插值器 解决卡顿问题

animator.setDuration(2000);

animator.setRepeatCount(ValueAnimator.INFINITE);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

setStartX((float) animation.getAnimatedValue());

}

});

animator.start();

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。