这个有好多种做法,我就讲二种方法,第一种方法就是自定义一个view,通过canvas画线就可以,只要把paint的width改成view的高度就行:
package com.day01; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.math.BigDecimal; /** * Created by zhouguizhijxhz on 2018/5/24. */ public class CustomProgress extends View implements View.OnClickListener { private Paint defaultPaint; private Paint rollPaint; private float percent = 0.0f; private Paint textPaint; private Handler mHandler = new Handler(); private MyRunnable myRunnable; public CustomProgress(Context context) { this(context, null); } public CustomProgress(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CustomProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); myRunnable = new MyRunnable(); initPaint(); setOnClickListener(this); } private void initPaint() { defaultPaint = new Paint(); defaultPaint.setColor(Color.parseColor("#999999")); defaultPaint.setStyle(Paint.Style.STROKE); rollPaint = new Paint(); rollPaint.setColor(Color.parseColor("#1C86EE")); rollPaint.setStyle(Paint.Style.STROKE); textPaint = new Paint(); textPaint.setColor(Color.parseColor("#202020")); textPaint.setTextSize(sp2px(15)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); } private int measureHeight(int heightMeasureSpec) { int mode = MeasureSpec.getMode(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (mode == MeasureSpec.AT_MOST) { height = 320; } return height; } private int measureWidth(int widthMeasureSpec) { int mode = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); if (mode == MeasureSpec.AT_MOST) { width = 320; } return width; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawDefaultProgressButton(canvas); drawRollProgressButton(canvas); drawText(canvas); } private void drawText(Canvas canvas) { if (null == canvas) { return; } if (percent == 0) { String text = "下载"; Paint.FontMetricsInt fm = textPaint.getFontMetricsInt(); canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2, getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint); } else if(percent>0) { Log.e("percent","percent------------>"+percent); String text = percent*100+ "%"; Paint.FontMetricsInt fm = textPaint.getFontMetricsInt(); canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2, getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint); mHandler.postDelayed(myRunnable,500); } } private void drawRollProgressButton(Canvas canvas) { if (null == canvas) { return; } rollPaint.setStrokeWidth(dp2px(getMeasuredHeight())); canvas.drawLine(0, 0, percent*getMeasuredWidth(), 0, rollPaint); } private void drawDefaultProgressButton(Canvas canvas) { if (null == canvas) { return; } defaultPaint.setStrokeWidth(dp2px(getMeasuredHeight())); canvas.drawLine(0, 0, getMeasuredWidth(), 0, defaultPaint); } private int dp2px(float dpValue) { float scale = getContext().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * px转换成dp */ private int px2dp(float pxValue) { float scale = getContext().getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } public int sp2px(float spValue) { final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @Override public void onClick(View v) { percent+=0.1f; invalidate(); } class MyRunnable implements Runnable{ @Override public void run() { if(percent>=1.0){ return; } BigDecimal bigDecimal = new BigDecimal(Float.toString(percent)); BigDecimal bigDecimal1 = new BigDecimal(Float.toString(0.1f)); percent=bigDecimal.add(bigDecimal1).floatValue(); postInvalidate(); } } }
第二种做法:
这个就是绘制矩形,关键是要用到canvas的clipRect()方法,也就是画布裁剪:
package com.day01; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.Handler; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.math.BigDecimal; /** * Created by zhouguizhijxhz on 2018/5/24. */ public class CustomProgress extends View implements View.OnClickListener { private Paint defaultPaint; private Paint rollPaint; private float percent = 0.0f; private Paint textPaint; private Handler mHandler = new Handler(); private MyRunnable myRunnable; public CustomProgress(Context context) { this(context, null); } public CustomProgress(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CustomProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); myRunnable = new MyRunnable(); initPaint(); setOnClickListener(this); } private void initPaint() { defaultPaint = new Paint(); defaultPaint.setColor(Color.parseColor("#999999")); defaultPaint.setStyle(Paint.Style.FILL); rollPaint = new Paint(); rollPaint.setColor(Color.parseColor("#1C86EE")); rollPaint.setStyle(Paint.Style.FILL); textPaint = new Paint(); textPaint.setColor(Color.parseColor("#202020")); textPaint.setTextSize(sp2px(15)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec); setMeasuredDimension(width, height); } private int measureHeight(int heightMeasureSpec) { int mode = MeasureSpec.getMode(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (mode == MeasureSpec.AT_MOST) { height = 320; } return height; } private int measureWidth(int widthMeasureSpec) { int mode = MeasureSpec.getMode(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); if (mode == MeasureSpec.AT_MOST) { width = 320; } return width; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawDefaultProgressButton(canvas); drawRollProgressButton(canvas); drawText(canvas); } private void drawText(Canvas canvas) { if (null == canvas) { return; } if (percent == 0) { String text = "下载"; Paint.FontMetricsInt fm = textPaint.getFontMetricsInt(); canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2, getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint); } else if(percent>0) { BigDecimal re1=new BigDecimal(Float.toString(percent)); BigDecimal re2=new BigDecimal(Float.toString(100.0f)); String text = re1.multiply(re2).floatValue()+"%"; Paint.FontMetricsInt fm = textPaint.getFontMetricsInt(); canvas.drawText(text, getWidth() / 2 - textPaint.measureText(text) / 2, getHeight() / 2 - (fm.bottom + fm.top) / 2, textPaint); mHandler.postDelayed(myRunnable,500); } } private void drawRollProgressButton(Canvas canvas) { if (null == canvas) { return; } canvas.save(); Rect rect = new Rect(0, 0, (int) (percent*getMeasuredWidth()), getMeasuredHeight()); canvas.clipRect(rect); canvas.drawRect(rect,rollPaint); canvas.restore(); } private void drawDefaultProgressButton(Canvas canvas) { if (null == canvas) { return; } canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),defaultPaint); } private int dp2px(float dpValue) { float scale = getContext().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * px转换成dp */ private int px2dp(float pxValue) { float scale = getContext().getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } public int sp2px(float spValue) { final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @Override public void onClick(View v) { percent+=0.1f; invalidate(); } class MyRunnable implements Runnable{ @Override public void run() { if(percent>=1.0){ return; } BigDecimal bigDecimal = new BigDecimal(Float.toString(percent)); BigDecimal bigDecimal1 = new BigDecimal(Float.toString(0.1f)); percent=bigDecimal.add(bigDecimal1).floatValue(); postInvalidate(); } } }
效果:
如果想要二边有圆形的,就使用第一种方式,而且paint上使用setStrokeCap(Paint.Cap.ROUND)这个方法加上线冒,如果是绘制矩形的这个方法是无效的.