android 自定义view 圆形进度条

前几天,公司来了一个项目,要做一个特别炫酷的界面,进度条呢就是其中之一了,用系统的进度条,然后光靠修改资源背景是达不到需求的,那就只好自己画一个了,同时文章最后将会提供demo下载,现在先来浏览下效果图吧。

<span style="white-space:pre">	</span>protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		/**
		 * 画最外层的大圆环
		 */
		int centre = getWidth() / 2; // 获取圆心的x坐标

		int radius = (int) (centre - roundWidth / 2); // 圆环的半径
		paint.setColor(roundColor); // 设置圆环的颜色
		paint.setStyle(Paint.Style.STROKE); // 设置空心
		paint.setStrokeWidth(roundWidth); // 设置圆环的宽度
		paint.setAntiAlias(true); // 消除锯齿
		canvas.drawCircle(centre, centre, radius, paint); // 画出圆环

		Log.e("log", centre + "");

		/**
		 * 画进度百分比
		 */
		paint.setStrokeWidth(0);
		paint.setColor(textColor);
		paint.setTextSize(textSize);
		paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体
		int percent = (int) (((float) progress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,<span style="white-space:pre">		</span>不然都为0
		float textWidth = paint.measureText(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间

		if (textIsDisplayable && percent != 0 && style == STROKE) {
			canvas.drawText(percent + "%", centre - textWidth / 2, centre
					+ textSize / 2, paint); // 画出进度百分比
		}

		paint.setStyle(Paint.Style.FILL_AND_STROKE); // 设置实心
		paint.setStrokeWidth(0);
		paint.setColor(Color.WHITE);

		/**
		 * 画圆弧 ,画圆环的进度
		 */

		// 设置进度是实心还是空心
		paint.setStrokeWidth(roundWidth); // 设置圆环的宽度
		paint.setColor(roundProgressColor); // 设置进度的颜色
		RectF oval = new RectF(centre - radius, centre - radius, centre
				+ radius, centre + radius); // 用于定义的圆弧的形状和大小的界限(个人理解就是求圆的直径上的俩点的<span style="white-space:pre">		</span>坐标值)

		switch (style) {
		case STROKE: {
			paint.setStyle(Paint.Style.STROKE);
			
			// 设置圆弧的线帽为圆形,这个也可以提出来当成自定义属性,自由度更广更方便
			paint.setStrokeCap(Paint.Cap.ROUND);
			canvas.drawArc(oval, 270, 360 * progress / max, false, paint); // 根据进度画圆弧,270度是12点钟方向

			//进度是刚开始还是已经结束了,用于判断在起始位置是否绘制圆点
			boolean isstartorstop = Math.sin(Math.toRadians(270 + 360
					* progress / max)) == -1;

			paint.setStyle(Paint.Style.FILL);
			paint.setColor(Color.WHITE);
			// 绘制12点钟和6点钟方向的圆点,绘制圆点的最重要的是要根据已知的条件算出圆点的圆心坐标
			if (topandbuttomcircle) {
				if (isdismisscircle) {
					if (!isstartorstop) {
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						paint.setAlpha(150);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx1 = (float) (centre + radius
								* Math.cos(Math.toRadians(270)));
						float cy1 = (float) (centre + radius
								* Math.sin(Math.toRadians(270)));
						canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);
						
						float cx11 = (float) (centre + radius
								* Math.cos(Math.toRadians(270)));
						float cy11 = (float) (centre + radius
								* Math.sin(Math.toRadians(270)));
						canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);

						paint.setAlpha(150);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx2 = (float) (centre + radius
								* Math.cos(Math.toRadians(90)));
						float cy2 = (float) (centre + radius
								* Math.sin(Math.toRadians(90)));
						canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);

						paint.setAlpha(255);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx21 = (float) (centre + radius
								* Math.cos(Math.toRadians(90)));
						float cy21 = (float) (centre + radius
								* Math.sin(Math.toRadians(90)));
						canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);
					}
				} else {
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx1 = (float) (centre + radius
							* Math.cos(Math.toRadians(270)));
					float cy1 = (float) (centre + radius
							* Math.sin(Math.toRadians(270)));
					canvas.drawCircle(cx1, cy1, roundWidth / 4, paint);

					paint.setAlpha(150);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx2 = (float) (centre + radius
							* Math.cos(Math.toRadians(90)));
					float cy2 = (float) (centre + radius
							* Math.sin(Math.toRadians(90)));
					canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);

					paint.setAlpha(255);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx21 = (float) (centre + radius
							* Math.cos(Math.toRadians(90)));
					float cy21 = (float) (centre + radius
							* Math.sin(Math.toRadians(90)));
					canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);
				}
			}
			// 绘制3点钟和9点钟方向的圆点
			if (leftandrightcircle) {
				if (isdismisscircle) {
					if (!isstartorstop) {
						paint.setAlpha(150);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx1 = (float) (centre + radius
								* Math.cos(Math.toRadians(0)));
						float cy1 = (float) (centre + radius
								* Math.sin(Math.toRadians(0)));
						canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);

						paint.setAlpha(255);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx11 = (float) (centre + radius
								* Math.cos(Math.toRadians(0)));
						float cy11 = (float) (centre + radius
								* Math.sin(Math.toRadians(0)));
						canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);

						paint.setAlpha(150);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx2 = (float) (centre + radius
								* Math.cos(Math.toRadians(180)));
						float cy2 = (float) (centre + radius
								* Math.sin(Math.toRadians(180)));
						canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);

						paint.setAlpha(255);
						// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
						float cx21 = (float) (centre + radius
								* Math.cos(Math.toRadians(180)));
						float cy21 = (float) (centre + radius
								* Math.sin(Math.toRadians(180)));
						canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);
					}
				} else {

					paint.setAlpha(150);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx1 = (float) (centre + radius
							* Math.cos(Math.toRadians(0)));
					float cy1 = (float) (centre + radius
							* Math.sin(Math.toRadians(0)));
					canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);

					paint.setAlpha(255);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx11 = (float) (centre + radius
							* Math.cos(Math.toRadians(0)));
					float cy11 = (float) (centre + radius
							* Math.sin(Math.toRadians(0)));
					canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);

					paint.setAlpha(150);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx2 = (float) (centre + radius
							* Math.cos(Math.toRadians(180)));
					float cy2 = (float) (centre + radius
							* Math.sin(Math.toRadians(180)));
					canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);

					paint.setAlpha(255);
					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					float cx21 = (float) (centre + radius
							* Math.cos(Math.toRadians(180)));
					float cy21 = (float) (centre + radius
							* Math.sin(Math.toRadians(180)));
					canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);
				}
			}
			// 绘制线头上的圆点,跟随进度旋转360度
			if (lineheadcircle) {
				// 如果在进度为零或者进度为100的时候不再绘制线头圆点
				if (!isstartorstop) {

					// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)
					// 角度加上270是为了使圆点在12点钟方向开始绘制,3点钟方向时默认时0度,顺时针方向角度依次<span style="white-space:pre">			</span>增大。
					float cx = (float) (centre + radius
							* Math.cos(Math.toRadians(270 + 360 * progress
									/ max)));
					float cy = (float) (centre + radius
							* Math.sin(Math.toRadians(270 + 360 * progress
									/ max)));
					canvas.drawCircle(cx, cy, roundWidth / 4, paint);
					Log.e("Math.sin",
							""
									+ Math.sin(Math.toRadians(270 + 360
											* progress / max)));
				}
			}
			break;
		}
		case FILL: {
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			if (progress != 0)
				canvas.drawArc(oval, 270, 360 * progress / max, true, paint); // 根据进度画圆弧
			break;
		}
		}

	}

 项目源码,点击下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值