Android 绘制百分比圆环进度条
来源:互联网 发布:kiss乐队 知乎 编辑:程序博客网 时间:2024/04/30 10:40
在学习自定义Vew的时候,看到一篇文章,http://blog.csdn.net/nugongahou110/article/details/49159189,然后顺着其思路写了一下,实现效果如下:
我们要做的事情:实现一个百分比的圆环进度条,包含三部分,分别是:
- 百分比文字
- 背景圆
- 动态圆环
我们要做的思路:
- 先分别绘制对应的图形;
- 使图形能动态变化;
- 文字显示百分比与圆环进度对应;
会涉及到的基本知识点:
- 自定义View 会重写三个方法;
- onMeasure()方法中,测量规则、测量大小、测量模式;
- TypedArray 获取自定义属性;
- canvas 绘制矩形内切圆;
自定义View PercentCircle.java:
public class PercentCircle extends View{ /** * 绘制百分比的圆,一共有三部分,分别是里面的文字、背景圆、圆环; * 思路:首先需要三支画笔, 设置画笔对应的属性等; */ private Paint mTextPaint; private Paint mBackgroundPaint; private Paint mRingPaint; private int mCircleX; private int mCircleY; private float mCurrentAngle; private RectF mArcRectF; private float mStartSweepValue; private float mTargetPercent; private float mCurrentPercent; private int mDefaultRadius = 60; private int mRadius; private int mDefaultBackgroundColor = 0xffafb4db; private int mBackgroundColor; private int mDefaultRingColor = 0xff6950a1; private int mRingColor; private int mDefaultTextSize; private int mTextSize; private int mDefaultTextColor = 0xffffffff; private int mTextColor; public PercentCircle(Context context) { super(context); init(context); } public PercentCircle(Context context, AttributeSet attrs) { super(context, attrs); // 自定义属性,attrs // 使用TypedArray TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentCircle); // 背景圆的半径 mRadius = typedArray.getInt(R.styleable.PercentCircle_radius, mDefaultRadius); // 背景圆的颜色 mBackgroundColor = typedArray.getColor(R.styleable.PercentCircle_background_color, mDefaultBackgroundColor); // 文字的颜色 默认白色 mTextColor = typedArray.getColor(R.styleable.PercentCircle_text_color, mDefaultTextColor); // 外圆环的颜色 mRingColor = typedArray.getColor(R.styleable.PercentCircle_ring_color, mDefaultRingColor); // Be sure to call recycle() when done with them typedArray.recycle(); init(context); } public PercentCircle(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context){ //圆环开始角度 -90° 正北方向 mStartSweepValue = -90; //当前角度 mCurrentAngle = 0; //当前百分比 mCurrentPercent = 0; //设置中心园的画笔 mBackgroundPaint = new Paint(); mBackgroundPaint.setAntiAlias(true); mBackgroundPaint.setColor(mBackgroundColor); mBackgroundPaint.setStyle(Paint.Style.FILL); //设置文字的画笔 mTextPaint = new Paint(); mTextPaint.setColor(mTextColor); mTextPaint.setAntiAlias(true); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setStrokeWidth((float) (0.025*mRadius)); mTextPaint.setTextSize(mRadius/2); //文字大小为半径的一半 mTextPaint.setTextAlign(Paint.Align.CENTER); //设置外圆环的画笔 mRingPaint = new Paint(); mRingPaint.setAntiAlias(true); mRingPaint.setColor(mRingColor); mRingPaint.setStyle(Paint.Style.STROKE); mRingPaint.setStrokeWidth((float) (0.075*mRadius)); //获得文字的字号 因为要设置文字在圆的中心位置 mTextSize = (int) mTextPaint.getTextSize(); } // 主要是测量wrap_content时候的宽和高,因为宽高一样,只需要测量一次宽即可,高等于宽 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measure(widthMeasureSpec), measure(widthMeasureSpec)); } // 当wrap_content的时候,view的大小根据半径大小改变,但最大不会超过屏幕 private int measure(int measureSpec){ int result = 0; //1、先获取测量模式 和 测量大小 //2、如果测量模式是MatchParent 或者精确值,则宽为测量的宽 //3、如果测量模式是WrapContent ,则宽为 直径值 与 测量宽中的较小值;否则当直径大于测量宽时,会绘制到屏幕之外; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if( specMode == MeasureSpec.EXACTLY){ result = specSize; }else { //result = 2*mRadius; //result =(int) (1.075*mRadius*2); result =(int) (mRadius*2 + mRingPaint.getStrokeWidth()*2); if(specMode == MeasureSpec.AT_MOST){ result = Math.min(result, specSize); } } return result; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); //1、如果半径大于圆心的横坐标,需要手动缩小半径的值,否则画到屏幕之外; //2、改变了半径,则需要重新设置字体大小; //3、改变了半径,则需要重新设置外圆环的宽度 //4、画背景圆的外接矩形,用来画圆环; mCircleX = getMeasuredWidth()/2; mCircleY = getMeasuredHeight()/2; if(mRadius > mCircleX){ mRadius = mCircleX; mRadius = (int) (mCircleX-0.075*mRadius); mTextPaint.setStrokeWidth((float) (0.025*mRadius)); mTextPaint.setTextSize(mRadius/2); mRingPaint.setStrokeWidth((float) (0.075*mRadius)); mTextSize = (int) mTextPaint.getTextSize(); } mArcRectF = new RectF(mCircleX-mRadius, mCircleY-mRadius, mCircleX+mRadius, mCircleY+mRadius); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //1、画中间背景圆 //2、画文字 //3、画圆环 //4、判断进度,重新绘制 canvas.drawCircle(mCircleX, mCircleY, mRadius, mBackgroundPaint); canvas.drawText(String.valueOf(mCurrentPercent)+"%", mCircleX, mCircleY+mTextSize/4, mTextPaint); canvas.drawArc(mArcRectF, mStartSweepValue, mCurrentAngle, false, mRingPaint); if(mCurrentPercent < mTargetPercent){ //当前百分比+1 mCurrentPercent+=1; //当前角度+360 mCurrentAngle+=3.6; //每10ms重画一次 postInvalidateDelayed(10); } //canvas.drawRect(mArcRectF, mRingPaint); } public void setTargetPercent(float targetPercent){ mTargetPercent = targetPercent; }}
0 0
- Android 绘制百分比圆环进度条
- Android自定义view动态绘制百分比圆环进度条
- Android 自定义圆环进度条 自适应显示百分比
- Android自定义控件之百分比圆环进度条
- Android自定义控件之百分比圆环进度条
- Android自定义控件之百分比圆环进度条
- Android自定义View:圆环带数字百分比的进度条
- canvas绘制圆环进度条
- canvas绘制圆环进度条
- Android圆环形自定义进度条控件的绘制
- canvas 绘制动态圆环进度条
- 用Canvas画圆环百分比进度条
- Android百分比下载进度条
- Android百分比下载进度条
- 圆环百分比
- 自定义控件Android圆环进度条
- Android自定义view 圆环进度条
- android自定义圆环控件 滑动选择百分比
- java接口回调(记录所学所整理,请多多指)
- DP专题--数的划分
- mysql安装
- 第十六周 -项目1 -算法验证 (7)归并排序 (8)基数排序
- 智能化时代
- Android 绘制百分比圆环进度条
- 面试感悟----一名3年工作经验的程序员应该具备的技能
- [LeetCode]Excel Sheet Column Title
- AOP 底层技术性能测试与比较
- Fourteenth records of career
- android中ListView的优化方案详解分析
- android:Intent的两种跳转
- POJ 2395 Out of Hay 笔记
- hdu 1495 非常可乐(bfs)