You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android极简手绘应用更改画笔颜色仅临时生效问题排查求助

问题原因排查方向

  • 你在DrawingView的onDraw方法里每次绘制都重新初始化了Paint对象,并且硬编码了默认颜色。哪怕你外部改了paint的颜色,下一次view触发重绘(比如点击后自动触发的invalidate)就会把颜色重置回默认值,而且因为onDraw会把所有路径用当前paint重绘,才会出现所有已画的线条都临时变色再恢复的现象。
  • 你没有为每一条已绘制的路径单独存储对应的颜色属性,所有路径共用同一个Paint实例。改颜色的时候全局paint变了,重绘所有路径都会变成新颜色,等到下次paint被重置回默认,所有路径又变回默认色。
  • 颜色选择按钮的点击事件里只改了临时变量的颜色,没有同步赋值给DrawingView里实际用于绘制的Paint实例,或者赋值后没有正确持久化这个颜色值,被其他逻辑又覆盖回默认值。
  • 你调用了DrawingView的invalidate()之后触发了额外的初始化逻辑,把画笔配置重置回了初始状态。

解决方案

1. 调整Paint初始化与绘制逻辑

不要在onDraw方法里初始化Paint,把Paint的实例化放到DrawingView的构造方法里仅初始化一次,同时新增数据结构存储每条路径对应的颜色、粗细属性,避免所有路径共用同一套Paint配置。

// DrawingView.kt 核心逻辑参考
class DrawingView(context: Context, attrs: AttributeSet) : View(context, attrs) {
    // 全局画笔仅在构造时初始化1次,默认颜色仅在这里赋值1次
    private val drawPaint = Paint().apply {
        color = DEFAULT_COLOR
        isAntiAlias = true
        strokeWidth = 10f
        style = Paint.Style.STROKE
        strokeJoin = Paint.Join.ROUND
    }
    // 存储每条路径的独立属性
    data class DrawPath(val path: Path, val color: Int, val strokeWidth: Float)
    private val drawPaths = mutableListOf<DrawPath>()
    private var currentColor = DEFAULT_COLOR
    private var currentStrokeWidth = 10f
    private val currentPath = Path()

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 遍历所有已完成的路径,用各自的属性绘制
        drawPaths.forEach { pathItem ->
            drawPaint.color = pathItem.color
            drawPaint.strokeWidth = pathItem.strokeWidth
            canvas.drawPath(pathItem.path, drawPaint)
        }
        // 绘制当前正在绘制的路径
        drawPaint.color = currentColor
        drawPaint.strokeWidth = currentStrokeWidth
        canvas.drawPath(currentPath, drawPaint)
    }

    // 对外暴露修改画笔颜色的方法
    fun setPaintColor(newColor: Int) {
        currentColor = newColor
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when(event.action) {
            MotionEvent.ACTION_DOWN -> currentPath.moveTo(event.x, event.y)
            MotionEvent.ACTION_MOVE -> currentPath.lineTo(event.x, event.y)
            MotionEvent.ACTION_UP -> {
                // 路径完成时保存路径+当前属性到列表
                drawPaths.add(DrawPath(Path(currentPath), currentColor, currentStrokeWidth))
                currentPath.reset()
            }
        }
        invalidate()
        return true
    }

    companion object {
        private const val DEFAULT_COLOR = Color.BLACK
    }
}

2. 修正颜色选择逻辑

点击颜色按钮时直接调用DrawingView暴露的setPaintColor方法即可,不要直接修改DrawingView内部paint,也不要重复初始化DrawingView实例。

// MainActivity.kt 颜色按钮点击示例
redColorBtn.setOnClickListener {
    drawingView.setPaintColor(Color.RED)
}

3. 额外检查项

  • 确认没有在onResume、onWindowFocusChanged这类生命周期方法里重复初始化DrawingView或者重置画笔颜色
  • 确认颜色选择逻辑里取到的颜色值是正确的,没有被后续逻辑覆盖

内容的提问来源于stack exchange,提问作者منوعات

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:54:02