Android Studio中Kotlin实现的ImageView静止时抖动问题
问题解决:ImageView静止时持续抖动
问题原因
宇航员静止时抖动的核心原因是:Astronaut类的move方法中,当目标坐标px/py和当前坐标x/y的差值小于步长(5)时,会出现来回增减的循环。比如px=102、x=100,第一次x +=5变成105,此时px < x,下一次x -=5回到100,反复切换就造成了视觉抖动。
解决方案
修改Astronaut的move方法,当当前坐标与目标坐标的差值小于等于步长时,直接将当前坐标设置为目标坐标,避免来回跳动;只有差值大于步长时,才保持逐步移动的平滑逻辑。
修改后的Astronaut类代码
import android.graphics.Canvas import android.graphics.drawable.Drawable class Astronaut(x:Int, y:Int, dx:Int, dy:Int, image: Drawable) : MyGameObject(x, y,dx, dy, image) { var px:Int=0 var py:Int=0 private val step = 5 // 提取步长为常量,方便后续调整 override fun move(canvas: Canvas) { // 处理X轴移动 val xDiff = px - x when { xDiff > step -> x += step xDiff < -step -> x -= step else -> x = px // 差值小于等于步长时直接到位 } // 处理Y轴移动 val yDiff = py - y when { yDiff > step -> y += step yDiff < -step -> y -= step else -> y = py // 差值小于等于步长时直接到位 } image.setBounds(x, y, x + width, y + height) image.draw(canvas) } }
额外优化建议
- 固定绘制帧率:当前SurfaceView线程未控制帧率,绘制频率不稳定可能加重抖动。可以在
run方法中添加睡眠控制,保证每帧耗时约16ms(对应60帧/秒):
override fun run() { while(isRunning) { if(!myHolder.surface.isValid) { continue } val startTime = System.currentTimeMillis() val canvas: Canvas = myHolder.lockCanvas() canvas.drawRect(0f, 0f, canvas.width.toFloat(), canvas.height.toFloat(), paint) for(gameObject in myGameObjects) { gameObject.move(canvas) } myHolder.unlockCanvasAndPost(canvas) // 控制帧率,确保每帧耗时约16ms val elapsedTime = System.currentTimeMillis() - startTime val sleepTime = 16 - elapsedTime if(sleepTime > 0) { try { Thread.sleep(sleepTime) } catch (e: InterruptedException) { e.printStackTrace() } } } }
- 校准触摸坐标:
MotionEvent.x/y是SurfaceView的局部坐标,若View存在padding或嵌套布局,需调整坐标值,避免目标位置偏差。
内容的提问来源于stack exchange,提问作者Talha Safdar
相关产品推荐
相关产品推荐

