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

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)
    }
}

额外优化建议

  1. 固定绘制帧率:当前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()
            }
        }
    }
}
  1. 校准触摸坐标:MotionEvent.x/y是SurfaceView的局部坐标,若View存在padding或嵌套布局,需调整坐标值,避免目标位置偏差。

内容的提问来源于stack exchange,提问作者Talha Safdar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:05:22