SurfaceView绘制线条出现异常画面的解决与高效绘制基础图形的方法
SurfaceView绘制线条出现异常画面的解决与高效绘制基础图形的方法
嗨,我来帮你搞定这个SurfaceView绘制的问题~你看到的随机乱画面,其实是SurfaceView的画布复用机制在搞鬼:每次调用lockCanvas()拿到的画布,会保留上一次绘制的残留内容(甚至可能是系统缓存的脏数据),你直接在上面画新线条,自然就会和旧内容叠加出混乱的效果啦。
第一步:解决当前的乱码问题
只需要在绘制新内容前,先把画布用背景色清干净就行。另外还有个小优化:不要每次点击都创建新的Paint对象,把它作为成员变量初始化,能减少不必要的资源消耗。
调整后的Activity代码如下:
package com.example.myapp import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import android.graphics.Color import android.graphics.Paint import android.view.SurfaceView import android.widget.Button class MainActivity : AppCompatActivity() { // 把Paint作为成员变量,复用它 private lateinit var myPaint: Paint override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val sv = findViewById<SurfaceView>(R.id.mysurfaceview) val b = findViewById<Button>(R.id.mybutton) // 初始化Paint,只做一次 myPaint = Paint().apply { color = Color.YELLOW isAntiAlias = true strokeWidth = 5f style = Paint.Style.FILL } b.setOnClickListener { val myCanvas = sv.holder.lockCanvas() myCanvas?.let { // 先清屏,用你想要的背景色,这里用白色示例 it.drawColor(Color.WHITE) // 再绘制线条 it.drawLine(20f, 20f, 450f, 520f, myPaint) sv.holder.unlockCanvasAndPost(it) } } } }
第二步:高效绘制基础图形的几个关键技巧
如果之后要做更复杂的绘制(比如连续画线条、矩形),这些技巧能帮你提升性能:
- 复用绘制对象:像
Paint、Path这类对象,尽量在初始化时创建,不要在绘制循环或点击事件里反复new,减少内存开销。 - 局部更新画布:如果只需要更新屏幕的某一块区域,可以给
lockCanvas()传一个Rect参数,指定要更新的范围,这样系统只会刷新这块区域,比全屏绘制更快。 - 用专门的绘制线程:如果是需要持续绘制的场景(比如动画、手写),不要在UI线程里做绘制操作,开一个单独的线程,配合
SurfaceHolder的生命周期回调(surfaceCreated、surfaceDestroyed)来管理绘制逻辑,避免阻塞UI。 - 保持画布状态一致:每次绘制前都要确保画布的状态是干净的,比如清屏、重置矩阵等,避免残留内容干扰新绘制的图形。
你的布局代码是没问题的,SurfaceView的权重设置也合理,这样按钮会占固定高度,SurfaceView填充剩余空间~
备注:内容来源于stack exchange,提问作者Cindy9
相关产品推荐
相关产品推荐

