You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在Kotlin中绘制矩形?解决跨Activity传数组至自定义View的问题

解决自定义View无法接收Activity传递数组的问题

看起来你遇到的核心问题是自定义View类没有接收外部数据的入口——你在Activity里拿到了从其他页面传来的各种ArrayList,但你的Canvass类并没有提供构造方法来接收这些数据,所以在onDraw方法里自然没法访问到这些数组。我来帮你一步步修正:

第一步:给自定义View添加带参数的构造方法

修改你的Canvass类,把需要用到的数组作为构造参数传入,并保存为类的属性:

class Canvass(
    context: Context,
    val layerHeight: ArrayList<Double>,
    val soilSpecificWeight: ArrayList<Double>,
    val cohesion: ArrayList<Double>,
    val frictionAngle: ArrayList<Double>,
    val mpEffectiveStress: ArrayList<Double>,
    val voidRatio: ArrayList<Double>,
    val compressionIndex: ArrayList<Double>,
    val recompressionIndex: ArrayList<Double>,
    val bearingCapacityIndex: ArrayList<Double>
) : View(context) {

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas) // 别忘了调用父类的onDraw方法
        canvas.drawRGB(255, 255, 255)
        val width = width.toFloat() // 直接转成Float减少后续类型转换
        
        // 用apply方法简化Paint初始化,代码更简洁
        val footingPaint = Paint().apply {
            setARGB(255, 128, 128, 128)
        }
        val textPaint = Paint().apply {
            setARGB(255, 255, 255, 255)
        }
        val brush3 = Paint().apply {
            setARGB(255, 138, 36, 36)
        }
        val brush4 = Paint().apply {
            setARGB(255, 138, 36, 36)
        }

        // 绘制基础矩形
        canvas.drawRect(width/2 -10, 0f, width/2 +10, 40f, footingPaint)
        canvas.drawRect(70f, 40f, width -70, 80f, footingPaint)

        // 修正循环:0..layerHeight.size会导致索引越界,改用until避免
        for(i in 0 until layerHeight.size){
            // 这里就可以用layerHeight[i]等数据绘制对应图层了
            // 示例:根据每层高度绘制不同的矩形
            val layerTop = 80f + (0 until i).sumOf { layerHeight[it].toFloat() }
            val layerBottom = layerTop + layerHeight[i].toFloat()
            canvas.drawRect(70f, layerTop, width -70, layerBottom, brush3)
        }
    }
}

第二步:在Activity中传递数据给自定义View

修改你的drawrect方法,创建Canvass实例时把从Intent获取的所有数组传进去:

fun drawrect(view: View){
    val layout1 = findViewById<ConstraintLayout>(R.id.layout1)
    
    // 安全转换Intent数据,避免类型转换异常导致崩溃
    val layerHeight = intent.getSerializableExtra("layerheight") as? ArrayList<Double> ?: arrayListOf()
    val soilSpecificWeight = intent.getSerializableExtra("soilspecificweight") as? ArrayList<Double> ?: arrayListOf()
    val cohesion = intent.getSerializableExtra("cohesion") as? ArrayList<Double> ?: arrayListOf()
    val frictionAngle = intent.getSerializableExtra("frictionangle") as? ArrayList<Double> ?: arrayListOf()
    val mpEffectiveStress = intent.getSerializableExtra("mpeffectivestress") as? ArrayList<Double> ?: arrayListOf()
    val voidRatio = intent.getSerializableExtra("voidratio") as? ArrayList<Double> ?: arrayListOf()
    val compressionIndex = intent.getSerializableExtra("compressionindex") as? ArrayList<Double> ?: arrayListOf()
    val recompressionIndex = intent.getSerializableExtra("recompressionindex") as? ArrayList<Double> ?: arrayListOf()
    val bearingCapacityIndex = intent.getSerializableExtra("bearingcapacityindex") as? ArrayList<Double> ?: arrayListOf()
    
    // 传递所有数据给Canvass实例
    val background = Canvass(
        this,
        layerHeight,
        soilSpecificWeight,
        cohesion,
        frictionAngle,
        mpEffectiveStress,
        voidRatio,
        compressionIndex,
        recompressionIndex,
        bearingCapacityIndex
    )
    layout1.addView(background)
}

额外提示

  1. 空指针防护:用as??:操作符安全转换数据,即使Intent中没有对应key,也会返回空ArrayList避免崩溃。
  2. 循环越界问题:原代码的0..layerheight.size会访问到超出数组长度的索引,0 until layerheight.size是更安全的写法。
  3. 图层绘制逻辑:示例中用累加高度的方式绘制分层矩形,你可以根据自己的需求调整绘制规则。

内容的提问来源于stack exchange,提问作者B. Ozturk

火山引擎 最新活动