这段时间用做一个飞行统计的模块,其中要做一个弧形展示效果,如图

做这个东西时,我们首先想到的是有没有现成的。于是就去github上找,找到了这个--https://github.com/lzyzsd/CircleProgress,大家有兴趣也可以去研究研究。本文参考的是其中的ArcProgress。其原理就是画弧和画字。。原理图:

先说画弧:

关键代码为:canvas.drawArc(rectF, startAngle, entityAngle, false, paint);
其中rectF为最外面的矩阵,startAngle为绘弧的开始角度,entityAngle为要画弧的最大值,false为不包含圆心,paint为画笔。

其次画字:

float bottomTextBaseline = getMeasuredHeight() - textPaint.descent();底部文字的基线
 canvas.drawText(bottomText, (getMeasuredWidth() - textPaint.measureText(bottomText)) / 2.0f, bottomTextBaseline, textPaint);

第一个参数为要画的文字,第二个参数为画字的起始x坐标,第三个为y坐标,第四个参数为文字画笔。

画字时的规则:参考http://blog.csdn.net/tianjf0514/article/details/7642656

接下来开始自定义我们的ArcView了,首先自定义属性,这个没什么可说的:

public ArcView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.Arc);this.radius = ta.getDimensionPixelSize(R.styleable.Arc_radius,0);this.entityAngle = ta.getInt(R.styleable.Arc_entity_angle, DEFAULT_ENTITY_ANGLE);this.initPercent = ta.getInt(R.styleable.Arc_init_percent,0);   //初始的百分值init(context);}

关键是测量我们的view的大小。一般来说,我们画的东西要在这个view可见范围内的中心。在onMeasure()方法中要计算出rectF(弧形的矩阵)。

上代码:

<pre name="code" class="java">protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Log.e("arcView","onMeasure");//整个内容的宽度int contentWidth = (int) (radius * 2 + out_stroke_width);//下面计算内容的高度float halfTemp = out_stroke_width / 2;float angle = (360 - entityAngle) / 2f;arcBottom2CenterHeight = (float) (radius * Math.cos(angle / 180 * Math.PI));int contentHeight = (int) (radius + arcBottom2CenterHeight + textPaint.descent() + out_stroke_width);setMeasuredDimension(resolveSize(contentWidth,widthMeasureSpec),resolveSize(contentHeight,heightMeasureSpec));float contentLeft,contentTop,contentRight,contentBottom;    //矩阵的左右上底if(getMeasuredWidth() == contentWidth){contentLeft = halfTemp;contentRight = contentWidth - halfTemp;}else{contentLeft = (getMeasuredWidth() - contentWidth) / 2 + halfTemp;contentRight = contentLeft + contentWidth - 2 * halfTemp;}if(getMeasuredHeight() == contentHeight){contentTop = halfTemp;contentBottom = contentWidth - halfTemp;}else{contentTop = (getMeasuredHeight() - contentHeight) / 2 + halfTemp;contentBottom = contentTop + contentWidth - 2 * halfTemp;}rectF = new RectF(contentLeft,contentTop,contentRight,contentBottom);}

接下来是ondraw方法:

protected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.e("arcView","draw"); //锁屏解锁后会再次调用ondraw()方法canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));paint.setStrokeWidth(default_stroke_width);paint.setColor(unfinishedStrokeColor);canvas.drawArc(rectF, startAngle, entityAngle, false, paint);paint.setStrokeWidth(out_stroke_width);paint.setColor(finishedStrokeColor);canvas.drawArc(rectF, startAngle, initSweepAngle, false, paint);//画下面文字textPaint.setTextSize(default_gray_text_size);textPaint.setColor(default_gray_text_color);float bottomTextBaseline = getMeasuredHeight() - textPaint.descent();canvas.drawText(bottomText, (getMeasuredWidth() - textPaint.measureText(bottomText)) / 2.0f, bottomTextBaseline, textPaint);//画上面文字float topTextBaseline = radius / 2 + out_stroke_width / 2;canvas.drawText(topText,(getMeasuredWidth() - textPaint.measureText(topText)) / 2.0f,topTextBaseline,textPaint);//画中心文字textPaint.setTextSize(default_percent_text_size);textPaint.setColor(default_percent_text_color);float centerTextBaseline = getMeasuredHeight() / 2 - textPaint.ascent() / 2;canvas.drawText(centerText,(getMeasuredWidth() - textPaint.measureText(centerText)) / 2.0f,centerTextBaseline,textPaint);}

手机锁屏后再亮屏,view的ondraw方法会调用,从下一个activity返回也会调用,结果是view可见是会调用ondraw()方法。

最后重写onSaveInstanceState和onRestoreInstanceState来保存和恢复数据

protected Parcelable onSaveInstanceState() {Log.e("arcView","onSaveInstanceState");Bundle bundle = new Bundle();bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());bundle.putFloat(INSTANCE_PROGRESS, initSweepAngle);return bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {Log.e("arcView","onRestoreInstanceState");if(state instanceof Bundle) {Bundle bundle = (Bundle) state;initSweepAngle = bundle.getFloat(INSTANCE_PROGRESS,0);super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));return;}super.onRestoreInstanceState(state);}

我们有可能显示百分数时需要一个animate过程,上代码:

/*第一中方式实现animatePercentprivate OverScroller scroller;public void animatePercent(int percent){if(scroller.isFinished()) {scroller.startScroll(0, 0, percent, 0, 2000);
//        scroller.fling(0,0,500,0,0,100,0,0);invalidate();}}@Overridepublic void computeScroll() {if(scroller.computeScrollOffset()){int tempPercent = scroller.getCurrX();setPercent(tempPercent);}super.computeScroll();}*/private final int ANIMATE_DURATION = 1000;private static final int SIXTY_FPS_INTERVAL = 1000 / 60;private long mStartTime;static final android.view.animation.Interpolator sInterpolator = new OvershootInterpolator();public void animatePercent(final int percent){mStartTime = System.currentTimeMillis();this.post(new Runnable() {@Overridepublic void run() {float t = interpolate();float currentPercent = 0 + t * percent;setPercent(currentPercent);if(t < 1){ArcView.this.postDelayed(this,SIXTY_FPS_INTERVAL);}}});}private float interpolate() {float t = 1f * (System.currentTimeMillis() - mStartTime) / ANIMATE_DURATION;t = Math.min(1f,t);return sInterpolator.getInterpolation(t);}

第一种方式在结束时有点卡顿的现象,不知道你们的手机有没有。我推荐第二种,当然了,我们也可以用属性动画来实现。

最后是效果图
源码:
http://yunpan.cn/cdgSG2ii4CzKh (提取码:560b)

自定义ArcView-构造拓展性高的view相关推荐

  1. 推荐一款拓展性高的开源仓库管理系统

      大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!   今天小编推荐一款开源仓储 ...

  2. java工作日报管理系统_GitHub - LovebuildJ/book-manager: JavaWeb图书管理系统,简单易用功能强大,可拓展性高,集成主流框架...

    book-manager 介绍 图书管理系统 请勿忽略更新日志, 会有详细的版本更新说明! 软件截图 在线API接口文档 登录 首页轮播 图书列表 图书上架 图书编辑 图书删除 图书借阅 图书检索 图 ...

  3. 到底什么是面向对象,面试中怎么回答。面向过程和面向对象的区别是什么。java跨平台特性以及java和C++的区别。面向对象的三大特性——封装、继承和多态。面向对象的高拓展性以及低耦合度怎么体现?

    Java语言具有的特点:面向对象.跨平台.多线程以及网络编程 1. 和C++的区别 1.1 Java隐蔽了C++的指针,避免指针直接操作,程序更加安全. 1.2 Java类继承只能单继承,避免了C++ ...

  4. Spring的控制反转以及依赖注入,控制反转使程序具有高拓展性。

    1. 控制反转(Inversion of Control, IOC) 将对象的创建.赋值.管理交给容器(Spring),通过xml文件即可修改对象的属性,不必修改源代码,具有高拓展性.各个模块间的对象 ...

  5. java.两个例子充分阐述多态的可拓展性

    下面我将以两个例子来充分阐述java中多态的可拓展性,作为一名优秀的程序员,就必须了解程序的可拓展性,非常利于程序后续的开发. 第一个例子:利用电脑的主板来作为例子,就我们所熟悉的电脑的主板,里面是不 ...

  6. (三) LtRecyclerView v2.x (自定义上拉和下拉刷新View)

    (一) 超简单自定义上下刷新布局-LtRecyclerView v2.x版本(基本使用) (二) LtRecyclerView v2.x (更多实用方法) (三) LtRecyclerView v2. ...

  7. log4j2动态修改日志级别及拓展性使用

    一.供参考的完整日志配置 <?xml version="1.0" encoding="UTF-8"?><!-- 配置LoggerConfig, ...

  8. Windows Azure真实案例:NeoGeo New Media --SQL Azure提高数字媒体资产解决方案的拓展性...

    公告    :本博客为微软云计算中文博客  的镜像博客.   部分文章因为博客兼容性问题  ,会影响阅读体验  .如遇此情况,请访问  原博客    . NeoGeo New Media 在一个持续制 ...

  9. Windows Azure真实案例:NeoGeo New Media --SQL Azure提高数字媒体资产解决方案的拓展性

    公告    :本博客为微软云计算中文博客  的镜像博客.   部分文章因为博客兼容性问题  ,会影响阅读体验  .如遇此情况,请访问  原博客    . NeoGeo New Media 在一个持续制 ...

  10. 数据密集型系统设计:可靠性、可拓展性及可维护性

    1.数据密集型应用 现今很多应用程序都是 数据密集型(data-intensive) 的,而非 计算密集型(compute-intensive) 的.因此CPU很少成为这类应用的瓶颈,更大的问题通常来 ...

最新文章

  1. 子div超出父div_菜鸟学 react props 子到父
  2. 考研计算机组成原电路知识,2021考研计算机大纲408计算机组成原理部分原文解析...
  3. 满有趣的屏幕快捷键;)
  4. 对python的认识作文500字_对阅读新认识作文500字
  5. [原]Oracle数据文件损坏的模拟和修复(一) |ORA-01578 data block corrupted|
  6. 直接输出代码_C语言入门 | 优秀代码(四)A—F
  7. C语言链表返回第n个到最后的节点的算法(附完整源码)
  8. 使用函数BAPISDORDER_GETDETAILEDLIST读取S/4HANA中Sales Order行项目数据
  9. ORACLE集群日志收集,【RAC】Oracle RAC集群环境下日志文件结构
  10. 小强的HTML5移动开发之路(32)—— JavaScript回顾7
  11. 正交法设计测试用例时可以使用的工具allpairs---生成正交表
  12. snm算法_基于SNM算法的大数据量中文地址清洗方法
  13. Java多个PDF文件合并成一个PDF文件
  14. 计算机制图的基本知识和技能,《计算机绘图基础》制图的基本知识和技能精讲.ppt...
  15. Esp8266对接阿里云物联网远程实时温度监控{探讨帖}
  16. C语言:使用函数输出一个数字构成的塔
  17. 朴素贝叶斯实战:人群收入预测(基于美国人口普查收入数据)
  18. matlab儒略日转日期,将日期(年、月、日)转换为儒略日编号并返回日期
  19. 固态硬盘故障表现及数据恢复方案
  20. 日志php-error错误日志查看

热门文章

  1. 关于安装mysql时出现安装错误之后的万能解决方案(目前解决了本人安装时的各种问题和同学的问题)
  2. Jupyter Notebook的使用02—两种模式的快捷操作
  3. html日期默认,html日期控件默认设置为当天日期
  4. 从sql2016导出数据库到sql2014
  5. AMESim中Demo简介
  6. XILINX FPGA数字信号处理——2、数字信号处理实现方法
  7. OpenGL超级宝典第7版 配置环境第一个程序
  8. 读嵌入式linux驱动程序设计从入门到精通1
  9. visio软件接口流程图_用Visio制作最专业的技术流程图教程
  10. Android 开发一定要看的15个实战项目