Android绘图应用无法在Canvas上绘图问题求助
绘图应用无法在Canvas上绘图的解决方案
你的代码存在三个关键问题,导致无法正常在Canvas上绘图,下面逐一说明并给出修复方案:
问题1:onDraw方法绘制逻辑错误
原代码在onDraw中错误地将缓存Bitmap绘制到自己创建的myCanvas,而非系统传入的用于显示到屏幕的canvas参数。正确逻辑应该是:把缓存的Bitmap绘制到屏幕的canvas,同时将当前路径绘制到缓存Bitmap的myCanvas,这样后续绘制才能保留历史内容。
问题2:ACTION_DOWN事件中坐标错误
触摸按下的处理里,moveTo方法错误传入两次touchX,导致起点Y坐标异常,应传入touchX和touchY。
问题3:未保存历史绘制路径
每次触摸抬起时直接新建CustomPath,之前绘制的路径会完全丢失,需要维护一个列表保存所有完成的路径,onDraw时遍历绘制所有历史路径。
修复后的DrawingView.kt代码
package com.example.drawingapp import android.annotation.SuppressLint import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.MotionEvent import android.view.View class DrawingView(context: Context, attrs: AttributeSet) : View(context, attrs) { private var myDrawPath: CustomPath? = null private var myCanvasBitmap: Bitmap? = null private var myDrawPaint: Paint? = null private var myCanvasPaint: Paint? = null private var myCanvas: Canvas? = null // 新增历史路径列表,保存已完成的绘制路径 private val pathList = ArrayList<CustomPath>() private var myBrushSize: Float = 0.toFloat() private var myColor = Color.BLACK init { drawingSetUp() } private fun drawingSetUp() { myDrawPaint = Paint() myDrawPath = CustomPath(myColor, myBrushSize) myDrawPaint!!.color = myColor myDrawPaint!!.style = Paint.Style.STROKE myDrawPaint!!.strokeJoin = Paint.Join.ROUND myDrawPaint!!.strokeCap = Paint.Cap.ROUND myCanvasPaint = Paint(Paint.DITHER_FLAG) myBrushSize = 20.toFloat() } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) myCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888) myCanvas = Canvas(myCanvasBitmap!!) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) // 将缓存的Bitmap绘制到屏幕的canvas上 canvas.drawBitmap(myCanvasBitmap!!, 0f, 0f, myCanvasPaint) // 绘制所有历史路径到缓存Bitmap for (path in pathList) { myDrawPaint!!.strokeWidth = path.brushThickness myDrawPaint!!.color = path.color myCanvas!!.drawPath(path, myDrawPaint!!) } // 绘制当前正在绘制的路径到屏幕 if (!myDrawPath!!.isEmpty) { myDrawPaint!!.strokeWidth = myDrawPath!!.brushThickness myDrawPaint!!.color = myDrawPath!!.color canvas.drawPath(myDrawPath!!, myDrawPaint!!) } } @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent?): Boolean { val touchX = event?.x ?: return false val touchY = event?.y ?: return false when (event.action) { MotionEvent.ACTION_DOWN -> { myDrawPath!!.color = myColor myDrawPath!!.brushThickness = myBrushSize myDrawPath!!.reset() // 修正坐标参数,使用touchX和touchY myDrawPath!!.moveTo(touchX, touchY) } MotionEvent.ACTION_MOVE -> { myDrawPath!!.lineTo(touchX, touchY) } MotionEvent.ACTION_UP -> { // 将完成的路径加入历史列表 pathList.add(myDrawPath!!) // 新建路径用于下一次绘制 myDrawPath = CustomPath(myColor, myBrushSize) } else -> return false } invalidate() return true } internal inner class CustomPath(var color: Int, var brushThickness: Float) : Path() }
其他文件说明
activity_main.xml和MainActivity.kt无需修改,当前配置是正确的。
内容的提问来源于stack exchange,提问作者Amandeep Singh
相关产品推荐
相关产品推荐

