小牛试刀,花了一个小时写了个网状图,如下

绘制的思路分成三部
1,首先绘制三条连接的长的直线,代码如下

    //画第一条竖线canvas.drawLine(0f, -r, 0f, r, mPaintLineBg)val averageAngle = 360f / PARTval y = (Math.sin(averageAngle / 2 / 180 * Math.PI) * r).toFloat()val x = (Math.cos(averageAngle / 2 / 180 * Math.PI) * r).toFloat()//斜线1canvas.drawLine(-x, y, x, -y, mPaintLineBg)//斜线2canvas.drawLine(-x, -y, x, y, mPaintLineBg)

2,然后绘制四个正六边形

 for (i in 1..4) {val xx = x * i / 4val yy = y * i / 4val rr = r * i / 4val path = Path()path.moveTo(0f, rr)path.lineTo(xx, yy)path.lineTo(xx, -yy)path.lineTo(0f, -rr)path.lineTo(-xx, -yy)path.lineTo(-xx, yy)path.close()canvas.drawPath(path, mPaintLineBg)}

最后绘制区域图形

  val path = Path()if (topRaw == 0f) {path.moveTo(0f, 0f)} else {path.moveTo(0f, -r * topRaw)canvas.drawCircle(0f, -r * topRaw, circleRaduis, mPaintCirlce)}if (topRightRaw == 0f) {path.lineTo(0f, 0f)} else {val y2 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * topRightRaw)).toFloat()val x2 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * topRightRaw)).toFloat()path.lineTo(x2, -y2)canvas.drawCircle(x2, -y2, circleRaduis, mPaintCirlce)}if (bottomRightRaw == 0f) {path.lineTo(0f, 0f)} else {val y3 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * bottomRightRaw)).toFloat()val x3 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * bottomRightRaw)).toFloat()path.lineTo(x3, y3)canvas.drawCircle(x3, y3, circleRaduis, mPaintCirlce)}if (bottomRaw == 0f) {path.moveTo(0f, 0f)} else {path.lineTo(0f, r * bottomRaw)canvas.drawCircle(0f, r * bottomRaw, circleRaduis, mPaintCirlce)}if (bottomLeftRaw == 0f) {path.lineTo(0f, 0f)} else {val y4 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * bottomLeftRaw)).toFloat()val x4 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * bottomLeftRaw)).toFloat()path.lineTo(-x4, y4)canvas.drawCircle(-x4, y4, circleRaduis, mPaintCirlce)}if (topLeftRaw == 0f) {path.lineTo(0f, 0f)} else {val y5 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * topLeftRaw)).toFloat()val x5 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * topLeftRaw)).toFloat()path.lineTo(-x5, -y5)canvas.drawCircle(-x5, -y5, circleRaduis, mPaintCirlce)}path.close()canvas.drawPath(path, mPaintLine)

最后贴上所有代码

class SpiderView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {companion object {val PART = 6}//画背景的private val mPaintLineBg = Paint(Paint.ANTI_ALIAS_FLAG)//画区域private val mPaintLine = Paint(Paint.ANTI_ALIAS_FLAG)//private val mPaintCirlce = Paint(Paint.ANTI_ALIAS_FLAG)// 宽高private var mWidth: Int = 0private var mHeight: Int = 0//中心的坐标private var mCenterX: Int = 0private var mCenterY: Int = 0//总进度private var count: Int = 100private var topRaw: Float = 0fprivate var topRightRaw: Float = 0fprivate var bottomRightRaw: Float = 0fprivate var bottomRaw: Float = 0fprivate var bottomLeftRaw: Float = 0fprivate var topLeftRaw: Float = 0fprivate val circleRaduis: Float = dp2px(3f)init {mPaintLineBg.color = Color.parseColor("#0000EE")mPaintLineBg.style = Paint.Style.STROKEmPaintLineBg.strokeWidth = dp2px(0.5f)mPaintLine.style = Paint.Style.FILLmPaintLine.color = Color.parseColor("#aaB22222")mPaintCirlce.style = Paint.Style.FILLmPaintCirlce.color = Color.parseColor("#0000EE")}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {val width = measureWidth(widthMeasureSpec)val height = measureHeight(heightMeasureSpec)val imageSize = if (width < height) width else heightsetMeasuredDimension(imageSize, imageSize)}/*** 测量宽度*/private fun measureWidth(measureSpec: Int): Int {val result: Intval specMode = View.MeasureSpec.getMode(measureSpec)val specSize = View.MeasureSpec.getSize(measureSpec)if (specMode == View.MeasureSpec.EXACTLY) {result = specSize} else if (specMode == View.MeasureSpec.AT_MOST) {result = specSize} else {result = specSize}return result}/*** 测量高度*/private fun measureHeight(measureSpecHeight: Int): Int {val result: Intval specMode = View.MeasureSpec.getMode(measureSpecHeight)val specSize = View.MeasureSpec.getSize(measureSpecHeight)if (specMode == View.MeasureSpec.EXACTLY) {result = specSize} else if (specMode == View.MeasureSpec.AT_MOST) {result = specSize} else {result = specSize}return result}override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {super.onSizeChanged(w, h, oldw, oldh)mWidth = w;mHeight = h;mCenterX = mWidth / 2mCenterY = mHeight / 2}@SuppressLint("DrawAllocation")override fun onDraw(canvas: Canvas) {super.onDraw(canvas)canvas.translate(mCenterX.toFloat(), mCenterY.toFloat())val r = Math.min(mCenterX, mCenterY).toFloat()//画第一条竖线canvas.drawLine(0f, -r, 0f, r, mPaintLineBg)val averageAngle = 360f / PARTval y = (Math.sin(averageAngle / 2 / 180 * Math.PI) * r).toFloat()val x = (Math.cos(averageAngle / 2 / 180 * Math.PI) * r).toFloat()//斜线1canvas.drawLine(-x, y, x, -y, mPaintLineBg)//斜线2canvas.drawLine(-x, -y, x, y, mPaintLineBg)for (i in 1..4) {val xx = x * i / 4val yy = y * i / 4val rr = r * i / 4val path = Path()path.moveTo(0f, rr)path.lineTo(xx, yy)path.lineTo(xx, -yy)path.lineTo(0f, -rr)path.lineTo(-xx, -yy)path.lineTo(-xx, yy)path.close()canvas.drawPath(path, mPaintLineBg)}val path = Path()if (topRaw == 0f) {path.moveTo(0f, 0f)} else {path.moveTo(0f, -r * topRaw)canvas.drawCircle(0f, -r * topRaw, circleRaduis, mPaintCirlce)}if (topRightRaw == 0f) {path.lineTo(0f, 0f)} else {val y2 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * topRightRaw)).toFloat()val x2 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * topRightRaw)).toFloat()path.lineTo(x2, -y2)canvas.drawCircle(x2, -y2, circleRaduis, mPaintCirlce)}if (bottomRightRaw == 0f) {path.lineTo(0f, 0f)} else {val y3 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * bottomRightRaw)).toFloat()val x3 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * bottomRightRaw)).toFloat()path.lineTo(x3, y3)canvas.drawCircle(x3, y3, circleRaduis, mPaintCirlce)}if (bottomRaw == 0f) {path.moveTo(0f, 0f)} else {path.lineTo(0f, r * bottomRaw)canvas.drawCircle(0f, r * bottomRaw, circleRaduis, mPaintCirlce)}if (bottomLeftRaw == 0f) {path.lineTo(0f, 0f)} else {val y4 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * bottomLeftRaw)).toFloat()val x4 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * bottomLeftRaw)).toFloat()path.lineTo(-x4, y4)canvas.drawCircle(-x4, y4, circleRaduis, mPaintCirlce)}if (topLeftRaw == 0f) {path.lineTo(0f, 0f)} else {val y5 = (Math.sin(averageAngle / 2 / 180 * Math.PI) * (r * topLeftRaw)).toFloat()val x5 = (Math.cos(averageAngle / 2 / 180 * Math.PI) * (r * topLeftRaw)).toFloat()path.lineTo(-x5, -y5)canvas.drawCircle(-x5, -y5, circleRaduis, mPaintCirlce)}path.close()canvas.drawPath(path, mPaintLine)}private fun sp2px(spValue: Float): Float {val fontScale = resources.displayMetrics.scaledDensityreturn (spValue * fontScale + 0.5f)}private fun dp2px(dp: Float): Float {val scale = resources.displayMetrics.densityreturn (dp * scale + 0.5f)}public fun setProgress(top: Int, topRight: Int, bottomRight: Int, bottom: Int, bottomLeft: Int, topLeft: Int) {topRaw = (top * 1f / count)bottomRightRaw = (bottomRight * 1f / count)bottomRaw = (bottom * 1f / count)bottomLeftRaw = (bottomLeft * 1f / count)topLeftRaw = (topLeft * 1f / count)topRightRaw = (topRight * 1f / count)invalidate()}public fun setCount(count: Int) {this.count = count}}

自定义view之网状图相关推荐

  1. android自定义View: 饼状图绘制(四)

    本系列自定义View全部采用kt 系统mac android studio: 4.1.3 kotlin version1.5.0 gradle: gradle-6.5-bin.zip 本篇效果: 画矩 ...

  2. 各种金融类的自定义 View,基金走势图、分时图、蜡烛图、各种指标等,一步一步构建庞大的基金自定 View...

    inancialCustomerView 项目地址:Tophold/FinancialCustomerView  简介:各种金融类的自定义 View,基金走势图.分时图.蜡烛图.各种指标等,一步一步构 ...

  3. 自定义view 太极八卦图

    自定义view 太极八卦图

  4. android显示字符串,Android自定义View用切图显示字符串

    近期开发收音机有个需求,将频率值以图片的形式显示出来(如结尾效果图所示).然而,一开始用TextView写出来的效果太丑了,提交上去肯定不合格.于是乎我想到了写一个自定义View,将频率的数字切图排布 ...

  5. android编程绘制扇形,分析实现Android自定义View之扇形图

    继承View基类,画了这样的扇形图 粗糙的样子^_^ 直接来步骤吧 1.分析 自定义View需要认真的分析下,里面还是会用到一些数学知识 首先是扇形该怎么表现 1. 扇形的外观是个圆弧,而且是围绕一个 ...

  6. android 自定义view: 蛛网/雷达图(三)

    本系列自定义View全部采用kt 系统mac android studio: 4.1.3 kotlin version1.5.0 gradle: gradle-6.5-bin.zip 本篇效果: 蛛网 ...

  7. 自定义view画走势图(一)

    在之前的许多项目中,在很多地方都需要有统计图来展示数据,其中用的比较多的就是折线图,本来一直想自己画的,无奈每次项目都是赶时间,基本都是在网上找个别人写好的,能基本满足需求的,就直接拿来用了.现在稍微 ...

  8. java 雷达图_Android雷达图(蜘蛛网图),自定义view之雷达图,正五边雷达图,分数图...

    最近业务要做分数雷达图,到网上找了很大,原理都差不多,但是要适用自己的业务,还需要微调.下面是我微调后的效果图 雷达图蜘蛛网.png 原理很简单 1,确定雷达图中心点的坐标 2,用正三角sin,反三角 ...

  9. Android自定义View:雷达图/蜘蛛网图

    运行效果图 雷达图结构分析 对雷达图进行结构拆分,得到一个清晰的思路,这些结构也就是需要绘制的部分.为了能够有更好的扩展性,我将它们作为可定制的属性暴露出来,以下是结构属性表: 结构 相关属性 描述 ...

最新文章

  1. TensorFlow基本使用
  2. A typical memory leak
  3. 【小练习】“表格”制作及答案
  4. 如何成为领袖? 学习任正非小沃森郭士纳
  5. 设置ASP.NET中的TextBox控件不缓存上次输入的信息
  6. T-Mobile美国加速开展5G实验:28GHz频段成为新宠
  7. 再来一波不错的学习资源
  8. 【算法】剑指 Offer 30. 包含min函数的栈
  9. OD常用快捷键(对比SoftICE)
  10. endnote导入参考文献及国标(Chinese standard)
  11. CIF、DCIF、D1分辨率是多少?
  12. Spring中Junit测试启动报错class path resource [xxx.xml] cannot be opened because it does not exist
  13. aws篇1 aws-cli的使用
  14. MySQL 5.7 深度解析: JSON数据类型使用
  15. 滤波电容值得选取-ESR
  16. 语音识别入门书籍推荐
  17. 产品经理进修第四天 产品增长怎么做
  18. 人工解决问题和用计算机解决问题的相同点,2计算机解决问题的过程.docx
  19. hyper-v自带坑
  20. Simple-fasterrcnn源码学习笔记(4)

热门文章

  1. 猎头辅助企业招聘能给企业带来什么?
  2. 国行new moto x升级android6,摩托罗拉Android6.0升级计划:全都在
  3. 事业群-部门-岗位辨析
  4. POJ 2389 Bull Math(FFT)
  5. Android开发之WIFI与网络连接处理
  6. Python扫雷游戏代码
  7. AAA企业信用评级的八大重要作用
  8. 电脑屏幕关不掉是为什么
  9. 武侯计算机实验小学教学质量怎么样,成都武侯区重点小学家长评价,择校经验...
  10. ewma 指数加权平均