第二阶段冲刺(四)

昨天学习了如何绘制简单的饼状图

遇到的困难是发现饼图百分比值加起来不是有时候大于1,有时候小于1,不知道怎么取值才能准确等于1

今天准备继续学习绘制饼状图

import android.content.Context
import android.graphics.*
import android.support.annotation.UiThread
import android.util.AttributeSet
import android.view.View
import com.example.lijingwen.defineview.databean.PieChartBean
 
/**
 * 自定义饼状图
 *
 * 不要设置wrap_content
 */
 
class PieChartView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
 
    private val startX = 300f
    private val startY = 300f
 
    var startAngle = 0f
        @UiThread
        set(value) {
            field = value
            invalidate()
        }
    private val colors = arrayOf(0xff8a2be2, 0xff4682b4, 0xff87ceeb, 0xff7cfc00, 0xffffe4b5, 0xff303F9F)
    var datas = ArrayList<PieChartBean>()
        @UiThread
        set(value) {
            field = value       //更新数据时刷新界面
            invalidate()
        }
 
    private val radius = 200     //半径
    private lateinit var angles: Array<Float?>
 
    /**
     * 实现饼状图绘制
     */
    override fun onDraw(canvas: Canvas?) {
        angles = arrayOfNulls(datas.size)   //存已经画的角度
 
        super.onDraw(canvas)
 
        canvas?.drawColor(0xff008080.toInt())   //背景绘制
 
        val itemCount = datas.size
        if (itemCount <= 0) {
            return
        }
 
        for (i in 0 until itemCount) {
            drawArc(canvas, i)
        }
 
    }
 
    private fun drawArc(canvas: Canvas?, i: Int) {
        var oneStartAngle = startAngle
        val paint = Paint()
        paint.isAntiAlias = true
        paint.style = Paint.Style.FILL
        paint.color = colors[i % colors.size].toInt()
        val percent = datas[i].percent
        if (percent <= 0) {
            return
        }
        val sweepAngle = (360f * percent) / 100      //圆弧对应的角度
        angles[i] = sweepAngle
 
        val rectF = RectF(startX, startY, startX + 2 * radius, startY + 2 * radius)          //在该矩形内
 
        for (index in 0 until i) {
            oneStartAngle += angles[index]!!
        }
 
        canvas?.drawArc(rectF, oneStartAngle, sweepAngle, true, paint)     //画扇形
 
        //drawText
        val halfAngle = oneStartAngle + sweepAngle * 0.5f      //圆心角的一半对应的角度
        val x = startX + radius + radius * Math.cos(halfAngle * 3.14 / 180f)       //角度对应的圆上的x坐标
        val y = startY + radius + radius * Math.sin(halfAngle * 3.14 / 180f)       //角度对应的圆上的y坐标
 
        val path = Path()
        path.moveTo(x.toFloat(), y.toFloat())
        if (x > startX + radius) {
            path.rLineTo(200f, 0f)
        } else {
            path.rLineTo(-200f, 0f)
        }
 
        val linePaint = Paint()
        linePaint.color = Color.BLACK
        linePaint.isAntiAlias = true
        linePaint.style = Paint.Style.STROKE
        linePaint.strokeWidth = 3f
 
        canvas?.drawPath(path, linePaint)      //guideLine
 
        val textPaint = Paint()
        textPaint.textSize = 40f
        textPaint.color = Color.BLACK
        textPaint.isAntiAlias = true
        textPaint.style = Paint.Style.FILL
        if (x > startX + radius) {
            canvas?.drawText(datas[i].title, (x + 220f).toFloat(), y.toFloat() + 10f, textPaint)    //title部分
        } else {
            canvas?.drawText(datas[i].title, (x - 300f).toFloat(), y.toFloat() + 10f, textPaint)
        }
    }
}
原文地址:https://www.cnblogs.com/lq13035130506/p/11003181.html