Android 自定义view - 绘制环形、扇形统计图

image.gif

介绍两种方式

第一种

先分析步骤:
  1. 覆盖view的onDraw方法
  2. 需要使用Paint类,绘制颜色和抗锯齿
  3. 使用canvas的drawArt方法,绘制扇形

1.定义变量

// 半径
private var radius = 250f
// 中心点
private var centerX = 0f
private var centerY = 0f
// 开始角度
private var startAngel = 0f
// 扫过角度
private val sweepAngle = 360 / 5f
// 定义几个颜色
private val mColors = intArrayOf(
  resources.getColor(R.color.color0), 
  resources.getColor(R.color.color1),
  resources.getColor(R.color.color2), 
  resources.getColor(R.color.color3), 
  resources.getColor(R.color.color4))

2.覆盖onDraw方法

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        this.centerX = (right - left) / 2f
        this.centerY = (bottom - top) / 2f
        initArc(canvas)
        initCircle(canbas)
    }

3.绘制扇形图

/**
  * 绘制扇形图
  * */
private fun initArc(canvas: Canvas?) {

        // 矩形区域
        val rect = RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
        val mPaint = Paint()

        mPaint.isAntiAlias = true

        for (i in 0..mColors.size) {
            mPaint.color = mColors[i]
            canvas?.drawArc(rect, startAngele, sweepAngle, true, mPaint)
            startAngle += sweepAngle
        }
}

4.再绘制一个中心白色的圆,半径为扇形图半径的一半

/**
 *中心圆
 *
 */
private fun initCircle(canvas: Canvas?) {
        val mPaint = Paint()
        mPaint.color = Color.parseColor("#ffffff")

        canvas?.drawCircle(centerX, centerY, ringRadius, mPaint)
}

做到现在,效果是这样的

111.png

但是我还想要点击效果啊!!!!

客观别急,我们换个姿势来

第二种

分析步骤

1.覆盖onDraw方法
2.使用path画出扇形
3.用region设置区域
4.复写onTouchEvent方法,判断点击区域

1.定义几个变量

private var regions: ArrayList? = null
private var changePos = -1
private val addRadius = 15

2.覆盖onDraw方法

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
//        initArc(canvas)
//        initCircle(canvas)

        this.centerX = (right - left) / 2f
        this.centerY = (bottom - top) / 2f
        drawArcForPath(canvas)
        initCircle(canvas)
    }

3.利用path绘制

private fun drawArcForPath(canvas: Canvas?) {

        regions = ArrayList()
        val paint = Paint()

        paint.isAntiAlias = true

        var currentRadius: Float

        for (i in 0 until mColors.size) {
            // 绘制点击的区域,增大半径
            currentRadius = if (i == changePos) radius + addRadius else {
                radius
            }
            // 矩形区域
            val rect = RectF(centerX - currentRadius, centerY - currentRadius, centerX + currentRadius, centerY + currentRadius)

            val path = Path()
            path.moveTo(centerX, centerY)
            path.arcTo(rect, startAngel, sweepAngel)

            startAngel += sweepAngel

            paint.color = mColors[i]
            val rectF = RectF()

            path.computeBounds(rectF, true)
            path.close()

            val region = Region()
            region.setPath(path, Region(rectF.left.toInt(), rectF.top.toInt(), rectF.right.toInt(), rectF.bottom.toInt()))

            regions?.add(region)

            paint.isAntiAlias = true

            canvas?.drawPath(path, paint)
        }

    }

4.设置点击事件

override fun onTouchEvent(event: MotionEvent?): Boolean {

        if (event?.action == MotionEvent.ACTION_DOWN) {
            val x = event.x
            val y = event.y

            for (i in 0 until regions!!.size) {
                // 判断点击位置,在哪个个扇形区域
                if (regions!![i].contains(x.toInt(), y.toInt())) {
                    changePos = i
                    invalidate()
                } else {
                    //changePos = -1
                    //invalidate()
                }

            }
        }

        return super.onTouchEvent(event)

    }

完结,撒花

你可能感兴趣的:(Android 自定义view - 绘制环形、扇形统计图)