onDraw方法未在我的自定义视图上绘制任何内容。我该如何解决?

问题描述 投票:0回答:1

我的自定义视图类的onDraw()方法有问题。我的自定义视图类扩展了Constraint Layout,我想使用canvas.drawLine()方法在其上绘制一些线条,但是当应用程序启动时,屏幕上什么都没有出现。为什么?请帮助我!

我编写的所有与代码相关的自定义视图。这是我视图的最简单形式,解决了此问题后,我将使用我编写但尚未使用的一些功能来扩展类:

class WeeklyBarDiagram @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null, defStyle: Int = 0): ConstraintLayout(context, attrs, defStyle) {

private val row = listOf(
    R.id.text_view_min_value,
    R.id.text_view_second_min_value,
    R.id.text_view_second_max_value,
    R.id.text_view_max_value
)
private val column = listOf(
    R.id.text_view_day1,
    R.id.text_view_day2,
    R.id.text_view_day3,
    R.id.text_view_day4,
    R.id.text_view_day5,
    R.id.text_view_day6,
    R.id.text_view_day7
)

private val columnDistances = listOf(0.108f, 0.222f, 0.337f, 0.452f, 0.567f, 0.681f, 0.796f)

private var maxValue: Float = 0f

private var statisticalData = listOf<Float>()
private var statisticalRatio = mutableListOf<Float>()

private var barLines = mutableListOf<Bar>()

private val paint = Paint().apply { color = Color.BLUE; strokeWidth = pxFromDP(5f) }

private var colorFirst = Color.parseColor("#353A85")
private var colorSecond = Color.parseColor("#959AC2")

private val barLineWidth: Float

private val singleBarLine: Boolean

private var isReadyToDraw = false

private val startPoint = FloatPoint() //bar starting point
private val stopPoint = FloatPoint() //bar ending point

private val firstPoint = FloatPoint() //first breaking point for two parted lines
private val secondPoint = FloatPoint() //second breaking point for two parted lines

init {
    LayoutInflater.from(context).inflate(R.layout.layout_diagram, this)

    val typedArray = context.obtainStyledAttributes(attrs, R.styleable.WeeklyBarDiagram)

    singleBarLine = typedArray.getBoolean(R.styleable.WeeklyBarDiagram_singleBarLine, false)

    colorFirst = typedArray.getColor(R.styleable.WeeklyBarDiagram_colorFirstPart, 0)
    colorSecond = typedArray.getColor(R.styleable.WeeklyBarDiagram_colorSecondPart, 0)

    barLineWidth =
        typedArray.getDimension(R.styleable.WeeklyBarDiagram_barLineWidth, pxFromDP(5f))

    when (typedArray.getInt(R.styleable.WeeklyBarDiagram_barLineCap, 0)) {
        0 -> paint.strokeCap = Paint.Cap.ROUND
        1 -> paint.strokeCap = Paint.Cap.BUTT
    }

    paint.strokeWidth = barLineWidth

    typedArray.recycle()
}

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

        if (!isReadyToDraw) return

        statisticalRatio.forEachIndexed { index, ratio ->

            startPoint.x = width * columnDistances[index]
            startPoint.y = height * 0.84f

            //Calculations end point and some other things which can be useful for parted line
            val distanceFromTopLine = height * (0.84f - 0.18f) * (1 - ratio)
            val distanceFromBottomLine = height * (0.84 - 0.18f) * ratio

            stopPoint.x = startPoint.x
            stopPoint.y = distanceFromTopLine + height * 0.18f

            if (singleBarLine) {
                paint.color = colorFirst
                canvas.drawLine(startPoint.x, startPoint.y, stopPoint.x, startPoint.y, paint)
            }

            Log.e("OnDraw", "Working")

        }

    }
}

//functionalities
fun setRowTexts(list: List<String>) {
    row.forEachIndexed { i, v -> findViewById<TextView>(v).text = list[i] }
    invalidate()
}

fun setColumnTexts(list: List<String>) {
    column.forEachIndexed { i, v -> findViewById<TextView>(v).text = list[i] }
    invalidate()
}

fun setMaxValue(maxValue: Float) {
    this.maxValue = maxValue
    //invalidate()
}

fun setStatistics(data: List<Float>) {
    this.statisticalData = data

    statisticalRatio.clear()
    statisticalData.forEach { statisticalRatio.add(it / maxValue) }

    isReadyToDraw = true
}

//utils
private fun pxFromDP(value: Float): Float {
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        value,
        context.resources.displayMetrics
    )
}

}

我已将合并标记用于布局内容xml

以及所有其他代码在主活动中:

class TestActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_test)

    diagram.setMaxValue(700f)
    diagram.setStatistics(listOf(600f, 150f, 250f, 400f, 100f, 550f, 300f))
    diagram.setRowTexts(listOf("100", "300", "500", "700"))
    diagram.setColumnTexts(listOf("3", "4", "5", "6", "7", "8", "9"))
}

}

android kotlin canvas android-constraintlayout ondraw
1个回答
0
投票

isReadyToDraw在调用onDraw()时为false。在setter调用后调用diagram.invalidate()以强制更新视图。

© www.soinside.com 2019 - 2024. All rights reserved.