Android自定义View之高仿QQ健康

我们都知道自定义View一般有三种直接继承View继承原有的控件对控件的进行修改重新拼装组合,最后一种主要针对于ViewGroup。具体的怎么做不是本文的所涉及的内容(本文是基于第一种方式实现的),还不太了解的请自行查询相关资料。这次这篇文章主要给大家带来一个高仿QQ健康的自定义View的实现,在介绍的过程中会对涉及到的自定义View相关知识点进行简单的说明,着重点还是在怎么是实现这个自定义View上。

好了,话不多说。我们来看看QQ健康页面的这个View吧。下面就是给大家讲解这个View怎么去实现。

来分析下这个View,最上面有一个圆弧,圆弧里面包含了一些文字,在圆弧的下面有几根竖条,很容易会想到这些竖条的长度是根据每天的步数来计算的。左下方是自己的头像,右下方可以点击查看。

我是使用的第一种方式,了解自定义View的同学肯定知道,第一种方式一般就是重写OnDraw方法利用Paint在Canvas中一笔一笔的画。

这个View的宽和高是有一定比例的。如果我们随意的给宽高,然后又没有一定的比例最后渲染出来的View肯定是很混乱的。所以我首先重写了下onMeasure方法

在初始化方法中有个mRatio是宽高的比例,是我根据截图用像素尺亮出来的,这个因人而异,可能每个人都会有不一样的度量结果,只要记住这个的作用是用来按照一定的比例绘制这个View的就OK了,这样做的好处就是不管这个View多大多小里面的内容都能够自适应,包括后面可能会会出现的一大堆数字,看到可能会有点晕,不用去管他。

知识点扫盲之MeasureSpec:他代表一个32位的int值,前两位代表SpecMode,后30位代表SpecSize。一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。

从代码中可以看到如果widthMode 是EXACTLY 或者AT_MOST,我们就将父布局传递过来的测量宽度作为View的宽度。如果不是这两种就将前面定义的默认的宽度来作为View宽度(这个一般不会用到)。宽度测量完了之后,就按照一定的比例计算出高度,然后就将这个高度作为我们View的高度,这样做,View的高度都是按照宽度来计算的,这样做的好处是我们在使用这个View的时候不会导致变形。

值得注意的是测量完了之后一定要调用 setMeasuredDimension这个方法。

下面我们再来看看onSizeChanged方法,这里是自适应的关键。

mArcCenterX 和mArcCenterY 是最上面那个圆弧的中心。我们都知道在Android中画一个圆弧需要一个这个圆弧的外接矩形,mArcRect就是这个外接矩形,mArcWidth和mBarWidth是对应画笔的宽度,在这个方法中我们对这些值作了初始化的工作。如果在构造函数里面取调用这个方法,宽和高是未知的。

到这里我们的初始化工作做得差不多了。下面来看看最重要的onDraw方法中都干了些什么,下面代码都是onDraw方法里面的(代码较长一次性截不完)

我注释的还是比较详细了,步骤也已经标明了,我相信仔细看肯定能看懂。对于绘制背景那里我多说两句,绘制背景的圆角我用的是贝塞尔曲线画的,当然你也可以直接使用canvas.drawRoundRect去画,但是对于这样一种需求:一个矩形上面两个角是圆角,下面的就是正常的方角,canvas.drawRoundRect显然办不到,然而贝塞尔曲线可以很容易办到,当然贝塞尔曲线的作用不仅仅是这个,它是非常强大的,只要是你能想到的他基本上都是能办到。这里有一篇关于贝塞尔曲线比较好的文章,感兴趣的可以去看看。

Android 自定义View高级特效,神奇的贝塞尔曲线

最后我们来看看怎么对右下角的那个查看添加点击事件吧

其实还是很简单,我们找到右下角对应的一个矩形区域,然后判断当前点击的坐标在不在这个矩形区域内就可以了。

值得注意的是要记得在初始化方法中加上这句代码

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

这句是关闭硬件加速,防止某些4.0的设备虚线显示为实线的问题,可以在AndroidManifest.xml时的Application标签加上android:hardwareAccelerated=”false”,这样整件应用都关闭了硬件加速,虚线可以正常显示,但是关闭硬件加速对性能有些影响,所以这里我们只对当前这个View关闭硬件加速就行了。

我们来看看最后我们实现的效果吧。

是不是还是挺不错的,并且还能自适应大小,和QQ的基本上一模一样。 由于代码量还是比较大,完整的贴出来比较 ,就不贴到这篇文章中了,需要完整版代码的请点击:

https://github.com/burgessjp/MaterialDesignDemo/blob/master/app/src/main/java/ren/solid/materialdesigndemo/view/QQHealthView.java

原文发布于微信公众号 - 非著名程序员(non-famous-coder)

原文发表时间:2016-04-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏韩伟的专栏

Unity2D手册翻译(三)

Sprite Editor 有时候一个Sprite纹理只包含一个图形原素,但是把多个相关的图形一起合并到一个图片中会更方便。例如,这个图片可能包含某一个角色的多...

42140
来自专栏前端菜鸟变老鸟

Sprite 从PS切图到具体实现完整过程

9910
来自专栏用户画像

H5新增的行内的语义元素

mark元素主要用来在视觉上向用户呈现那些需要突出显示或高亮显示的文字,其比较典型的应用就是在搜索结果中高亮显示搜索关键词。

10620
来自专栏大数据

前端女程序员教你,图片加载时,使用 SVG 作为图片 placehold

前言:使用 SVG 作为占位符不但可以减少数据大小还可以达到不错的显示效果。 不同类型的图片 placehold ? 请点击此处输入图片描述 对于图片占位符,通...

27490
来自专栏三流程序员的挣扎

Android 优化——应用瘦身

11810
来自专栏非著名程序员

代码实验室--带你一步步理解使用 ConstraintLayout

? 说明 这次 IO 给开发者带来了很多惊喜, ConstraintLayout 是其中较为实用的之一. Google 第一时间发布了官方的代码实验室指导教程...

25460
来自专栏java一日一条

简单好看的Android圆形进度条对话框开源库

本文介绍CircleProgressDialog开源库的使用及实现的详细过程,该开源库主要实现以下几个功能:

26720
来自专栏非著名程序员

Android自定义下拉刷新动画--仿百度外卖下拉刷新

? 好久没写博客了,小编之前一段时间一直在找工作,从天津来到了我们的大帝都,感觉还不错。好了废话不多说了,开始我们今天的主题吧。现如今的APP各式各样,同样也...

200100
来自专栏简书专栏

基于Excel2013的合并计算

工作组、求和、利用函数randbetween、合并计算 比如在excel表格中填入=randbetween(1,10),输入时如果需要补全要用鼠标点击,不能按...

14010
来自专栏Python小屋

Python使用tkinter编写图片浏览程序

代码要点:1)使用tkinter的Label显示图片;2)tkinter的PhotoImage支持的图片格式较少,使用pillow扩展库的Image和Image...

63090

扫码关注云+社区

领取腾讯云代金券