一、简介

1、本篇博文给大家介绍一个圆形进度条控件的绘制,首先看一下效果,如下:当点击圆形按钮时,开始加载条,当松开时,进度条回归其实位置;

二、结构分析

为了达到以上效果,我们首先要清楚改控件的结构和制作思路,首先我分析一下我制作时的结构,如下结构图:

结构如上,根据结构图,我说明一下我的制作思路,步骤如下:

1、首先取到控件的高度与宽度,取二者间的最小值,已这个最小值为边长(也可以比这个值小一点),控件最中心为中心点,获得一个正方形,如结构图中1所示;

2、以正方形的边长一半为半径,减去你想要的进度条宽度,获得内部圆的半径,一中心点为圆点绘制内部圆,如结构图中3所示;

3、以外部正方形为基准,绘制根据百分比绘制圆弧,如结构图中4所示;

三、代码分析

结构如上所述,我们现在来看看具体的代码实现

1、控件的属性参数:

   private static final int DOWN_STATE_DELAYED = 0;// 按下按钮触发状态private static final int DOWN_STATE_ANGLE_CHANGE = 2;// 与DOWN_STATE_DELAYED配对使用,叠加弧度状态private static final int UP_STATE_DELAYED = 1;// 松开按钮触发状态private static final int UP_STATE_ANGLE_CHANGE = 3;// 与UP_STATE_ANGLE_CHANGE配对使用,递减弧度状态private static final int ADD_ANGLE = 3;// 按下按钮每次叠加的弧度private static final int SUBTRACT_ANGLE = 6;// 松开按钮后每次递减的弧度public static final String PIE_COLOR = "#FF6B5B";// 进度条颜色public static final String NORMAL_TEXT_COLOR = "#596569";// 常态时内部中心圆字体颜色值public static final String CILCK_TEXT_COLOR = "#1FB9ED";// 点中时内部中心圆字体颜色值public static final String INSIDE_CIRCLE_COLOR = "#E2E2E2";// 内部中心圆背景颜色值public static final int PROGRESS_LINE_WIDTH = 18;// 进度条宽度private int viewWidthHeight;// 包含饼图的正方形private int width;// 整个View的宽private int height;// 整个View的高private int total;// 进度值private float radius;// 饼图半径private int titleSize = 15;// 文字大小private float startA = -90;// 起始角度private float angle;// 叠加角度private Paint paint;// 画笔private RectF oval;// 设置外部正方形private Context context;// 上下文对象private boolean downAction;// 是否按下private boolean upAction;// 是否抬起private int clickX;// 按下时X轴的位置private int clickY;// 按下时Y轴的位置private int moveX;// 移动时X轴的位置private int moveY;// 移动时Y轴的位置

2、适配方法(针对不同屏幕,所对应的PX不同)

/*** dip转px* @param context* @param dpValue* @return*/public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}/*** sp转px* @param context* @param dpValue* @return*/public static int sp2px(Context context, float spValue) {final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (spValue * fontScale + 0.5f);}

3、设置各个尺寸,编写构造函数

    // 测量尺寸protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}// 布局@SuppressLint("DrawAllocation")@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {if (changed) {width = getWidth();// 获取控件宽度height = getHeight();// 获取控件高度viewWidthHeight = Math.min(getWidth(), getHeight());// 获取控件宽高最小值radius = viewWidthHeight / 3f;// 设置外圆半径oval = new RectF(width / 2 - radius, height / 2 - radius, width / 2+ radius, height / 2 + radius);// 设置包含外圆的正方形}super.onLayout(changed, left, top, right, bottom);}public PieProgressSelfView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;// 初始画笔paint = new Paint();paint.setAntiAlias(true);}

4、绘制中心圆以及圆弧

   /*** 画进度弧线* * @param canvas*/private void drawProgressCircle(Canvas canvas) {paint.setStyle(Paint.Style.FILL);paint.setColor(Color.parseColor(PIE_COLOR));// System.out.println("startA=" + startA);// System.out.println("angle=" + angle);canvas.drawCircle(width / 2,height / 2 - radius+ ScreenUtil.dip2px(context, PROGRESS_LINE_WIDTH / 2),ScreenUtil.dip2px(context, PROGRESS_LINE_WIDTH / 2), paint);// 绘制进度条起点的半弧形canvas.drawCircle(width/ 2+ getSin(radius- ScreenUtil.dip2px(context,PROGRESS_LINE_WIDTH / 2), angle),height/ 2- getCos(radius- ScreenUtil.dip2px(context,PROGRESS_LINE_WIDTH / 2), angle),ScreenUtil.dip2px(context, PROGRESS_LINE_WIDTH / 2), paint);// 绘制进度条终点的半弧形canvas.drawArc(oval, startA, angle, true, paint);// 画扇形}/*** 画内部圆* * @param canvas*/private void drawInsideCircle(Canvas canvas) {paint.setStyle(Paint.Style.FILL);paint.setColor(Color.parseColor(INSIDE_CIRCLE_COLOR));canvas.drawCircle(width / 2, height / 2,radius - ScreenUtil.dip2px(context, PROGRESS_LINE_WIDTH), paint);}/*** 根据弧度与斜边获取cos的值* * @param x* @param Angle* @return*/private float getCos(float x, double Angle) {return (float) (x * Math.cos(Math.toRadians(Angle)));}/*** 根据弧度与斜边获取sin的值* * @param x* @param Angle* @return*/private float getSin(float x, double Angle) {return (float) (x * Math.sin(Math.toRadians(Angle)));}/*** 写文字* * @param canvas* @param title* @param color*/private void writeClickText(Canvas canvas, String title, String color) {paint.setTextSize(ScreenUtil.sp2px(context, titleSize));paint.setColor(Color.parseColor(color));if (title != null) {// 写标题canvas.drawText(title, width / 2 - paint.measureText(title) / 2,height / 2 + ScreenUtil.sp2px(context, titleSize) / 2,paint);}}// 绘制protected void onDraw(Canvas canvas) {super.onDraw(canvas);writeClickText(canvas, "点击", NORMAL_TEXT_COLOR);if (upAction || downAction) {drawProgressCircle(canvas);}drawInsideCircle(canvas);if (upAction || downAction) {writeClickText(canvas, (int) ((angle * 100) / 360) + "%",CILCK_TEXT_COLOR);} else {writeClickText(canvas, "点击", NORMAL_TEXT_COLOR);}}

5、设置点击加载,松开倒加载的效果

   // 判断是否在某个圆内private boolean isInCircle(int x, int y) {PointF p = new PointF(width / 2, height / 2);int distance = (int) Math.sqrt((p.x - x) * (p.x - x) + (p.y - y)* (p.y - y));if (distance <= (radius - ScreenUtil.dip2px(context, 3))) {return true;} else {return false;}}private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {switch (msg.what) {case DOWN_STATE_DELAYED:if (angle < 360) {// 当弧度小于360时,延时30ms跳转到2mHandler.sendEmptyMessageDelayed(DOWN_STATE_ANGLE_CHANGE,30);}break;case UP_STATE_DELAYED:if (angle > 0) {// angle = 0;mHandler.sendEmptyMessageDelayed(UP_STATE_ANGLE_CHANGE, 1);} else {angle = 0;upAction = false;downAction = false;invalidate();}break;case DOWN_STATE_ANGLE_CHANGE:angle = angle + ADD_ANGLE;if (downAction) {invalidate();mHandler.sendEmptyMessage(DOWN_STATE_DELAYED);}break;case UP_STATE_ANGLE_CHANGE:angle = angle - SUBTRACT_ANGLE;if (upAction) {invalidate();mHandler.sendEmptyMessage(UP_STATE_DELAYED);}break;default:break;}return false;}});@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {case MotionEvent.ACTION_DOWN:clickX = (int) event.getX();clickY = (int) event.getY();if (isInCircle(clickX, clickY)) {// 点击在内圆中时启动进度downAction = true;upAction = false;mHandler.sendEmptyMessage(DOWN_STATE_DELAYED);}break;case MotionEvent.ACTION_MOVE:moveX = (int) event.getX();moveY = (int) event.getY();if (!isInCircle(moveX, moveY)) {// 手指移动出内圆后,停止加载downAction = false;upAction = true;mHandler.sendEmptyMessage(UP_STATE_DELAYED);}break;case MotionEvent.ACTION_UP:// 抬起手指后,停止加载downAction = false;upAction = true;mHandler.sendEmptyMessage(UP_STATE_DELAYED);break;default:break;}return true;}

以上,为我设计的圆形进度条,大家可以根据自己的需求进行更改,望大家指点;

android圆形进度条相关推荐

  1. android椭圆进度,Android 圆形进度条

    可设置 线性渐变-背景色-进度条颜色-圆弧宽度 效果图 普通效果.png 渐变效果 改变弧度效果 步骤一:新建自定义控件CirclePercentView继承View(代码可直接复制使用) impor ...

  2. 超简单的Android圆形进度条

    效果图: 代码优化/简化.教科书级别注释.复制粘贴即可用 代码: package com.zistone.factorytest0718.view;import android.content.Con ...

  3. android 圆形拖动条,Android圆形进度条自定义

    自定义圆形进度条 示例.png 示例 (2).png 示例 (3).png 示例 (4).png 实现 override fun onSizeChanged(w: Int, h: Int, oldw: ...

  4. android圆形进度条ProgressBar颜色设置

    原帖地址:http://www.apkbus.com/android-19012-1-1.html xml布局文件需加入如下的进度条构件: Java代码 <ProgressBar android ...

  5. android圆环进度条动画,Android 圆形进度条,类似一些计步软件的进度显示!

    Android 圆形的进度条,类似于一些计步的进度显示.其实也是我们项目中的效果,只不过后来迭代中改进了,所以现在才拿出来.浏览更多安卓源码 usage android:id="@+id/a ...

  6. Android圆形进度条动画

    说明: 分析了一个git项目:https://github.com/youmu178/ArcProgressBar 效果图: 关键代码: 调用MainActivity.java mArcProgres ...

  7. Android圆形进度条,显示百分比

    自定义View在我心中一直属于比较难的范围,但是别人能写为什么我写不出来呢,所以静下心来,根据网上参考,自己写了一个比较普遍的圆环百分数的View,经分析(本Demo)主要核心就一个线程,定时刷新界面 ...

  8. 自定义绘制圆形进度条

    自定义圆形进度条 Android 圆形进度条控件 demo示例 1.定义 attrs.xml <?xml version="1.0" encoding="utf-8 ...

  9. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

最新文章

  1. 扫码下单支持同桌单人点餐FAQ
  2. Python可视化(matplotlib)在图像中添加文本和标记(Text and Annotation)
  3. 18香警告:一个女生勿近的邪恶开源项目...
  4. redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?...
  5. c/c++使用gsoap发布和调用webservice
  6. (33)调试驱动程序
  7. Divine Array 思维,模拟,结论
  8. OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱
  9. 写linux程序测试吞吐量,Linux下测试磁盘性能(IO、吞吐量)
  10. wx5 mysql起不来_mysql(四)—–mysql主从配置-wx5bd1240aa20ac的博客
  11. Java Finalizer和Java文件输入/输出流
  12. python下载之后无法启动_安装后启动时,适用于Python的Eric IDE崩溃
  13. workbook加载文件路径_【Python】文件重命名(按照Excel清单)
  14. Android与iOS/WP8跨平台整合设计与开发_专栏
  15. 学计算机要选什么科目,实行新高考后 想学计算机专业怎么选科
  16. word 2019 方框中打勾
  17. excel冻结窗格参与排序_冻结窗格在Excel中消失
  18. 拆弹实验-phase_4
  19. Elasticsearch Field Options Norms
  20. 编码规则的发展历程(通俗版)

热门文章

  1. LAMP(CentOS)环境详细配置步骤
  2. 底部点击加载更多功能的简单实现
  3. 九个Web开发者必备的软技能
  4. vue3状态管理pinia、 路由useRouter
  5. iOS开发可以调节屏幕亮度并且上传APPstore
  6. 任意输入一个年份 判断是否为闰年
  7. React 音乐播放器
  8. 精益管理学会|什么是ECRS改善方法?
  9. layui select(下拉框)修改事件监听
  10. 刷脸支付会以迅雷不及掩耳之势布局未来