本文共 2010 字,大约阅读时间需要 6 分钟。
写论文忙里偷闲写了一个蜘蛛网图的自定义view,支持多重属性
有图才能有真相,下面先上图
主要支持网格颜色、tag文本、覆盖区域颜色、透明度的属性改变,具体使用可以参见我的github,求互粉求start,下面主要介绍一下实现这个自定义控件的几个关键点。
首先要知道这个控件需要暴露出哪些属性,创建一个attrs.xml
通常是在自定义view中通过
TypedArray
来获取属性,使用完后之后使用recycle回收,如果属性较多的话写到一个文件中会显得过于臃肿,个人比较喜欢单独用一个类来处理,然后在自定义view中new一个出来这样会显得很简洁,具体可以参见我的代码。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawNet(canvas); drawText(canvas); drawRegion(canvas); }
画网主要分为俩大部分,画六边形和径线,
画六边形,每次先移动到圆心位置,A点,然后使用lineTo划线,如下图所示 使用到了一点正余弦的数学知识比较简单。画文本需要自己做一下微调,要是不微调就会出现下图所示的问题
首先我们要获取字符的宽和高 宽比较简单
float dis = textPaint.measureText(titles[i]);//获取文本长度
高就涉及到一些比较生僻的api的使用
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); float fontHeight = fontMetrics.descent - fontMetrics.ascent; //文字的高度
关于文字的更详细的讲解可以参阅
最后就是画区域同样是利用path的moveTo和lineTo俩个属性来画线,然后path.close闭合曲线比较简单
一开始没有写这个发现wrap_content无法使用(使用了还是出现match_parent的效果),这是由于使用wrap_content时候此时sepcMode为AT_MOST,此时宽高为parentSizes即父容器的大小,因此跟使用match_parent效果一致,做了如下改写:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize =MeasureSpec.getSize(widthMeasureSpec); int heighSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heighSpecSize =MeasureSpec.getSize(heightMeasureSpec); if(widthSpecMode==MeasureSpec.AT_MOST&&heighSpecMode==MeasureSpec.AT_MOST){ setMeasuredDimension(200,200); }else if(widthSpecMode==MeasureSpec.AT_MOST){ setMeasuredDimension(200,heighSpecSize); }else if(heighSpecMode==MeasureSpec.AT_MOST){ setMeasuredDimension(widthSpecSize,200); } }
这样就可以避免这个问题了。
总的看来这个自定义控件比较基础,看在码这么多字也不容易的份上,互粉点个start吧
转载:http://blog.csdn.net/xsf50717/article/details/50876518