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

安卓开发:点击屏幕移动圆形后其无理由异常加速问题咨询

核心问题出在OnGlobalLayoutListener没有及时移除

你的OnGlobalLayoutListener没有在首次触发后移除,每次根布局发生重绘时,都会重复触发回调,每次回调都会执行一次leHandleur.post(mover),相当于给Handler的消息队列新增一个mover执行任务。
而mover内部每次执行完都会调用leHandleur.postDelayed(this, 0)循环触发自身,所以每多一次post,后续每一轮刷新都会多执行一次移动逻辑:

  • 首次触发后,每轮刷新移动1次moverSpeed
  • 第二次触发回调后,每轮刷新移动2次moverSpeed,速度翻倍
  • 后续每触发一次,速度就叠加一次
    你每次点击圆形时,会执行scoreTxt.setText(newScore)更新分数,如果TextView的宽高随内容变化,就会触发根布局重绘,进而触发OnGlobalLayoutListener,所以每次点击后速度都会变快。

解决方案

  1. 在OnGlobalLayoutListener首次执行完成后立即移除监听器,避免重复触发:
ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        xWidth = rootLayout.getWidth() - toMove.getWidth() - moverSpeed;
        yHeight = rootLayout.getHeight() - toMove.getHeight() - moverSpeed;
        Log.d("Max_Heigth_Width", "onCreate: \nHeight: " + yHeight + "\nWidth: " + xWidth);
        // 启动移动逻辑前先移除已存在的回调,避免重复执行
        leHandleur.removeCallbacks(mover);
        leHandleur.post(mover);
        // 移除当前监听器
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    }
};
rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
  1. 可选优化:你当前设置的postDelayed延迟为0,会尽可能频繁的执行移动逻辑,建议调整为16ms(和普通60Hz屏幕的刷新周期对齐),降低不必要的性能消耗:
leHandleur.postDelayed(this, 16);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:09:02