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

Android字谜开发:获取TextView坐标始终为0的问题求解

解决Android中TextView获取位置返回0的问题

你遇到的问题本质上是调用位置获取方法的时机太早——在View完成布局测量和绘制之前,这些方法返回的坐标自然都是0。Android的View有一套完整的布局流程:先执行measure(测量尺寸),再执行layout(确定位置),最后才是draw(绘制)。只有在layout阶段完成后,getLeft()、getLocationInWindow()这类方法才能拿到真实的坐标值。

下面给你几个可靠的解决方案,按场景选择即可:

方法一:使用View.post()延迟执行

这是最简单的解决方案,post()提交的Runnable会被加入View的消息队列,等到View完成布局后再执行:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_game_layout);
    
    // 把位置获取的逻辑放到post里
    findViewById(R.id.tablojj).post(new Runnable() {
        @Override
        public void run() {
            konumal();
        }
    });
}

public void konumal() { 
    int[] korr = new int[2]; 
    TextView targetTv = findViewById(R.id.tablojj);
    targetTv.getLocationInWindow(korr); 
    Log.w("Dikkat", "x : " + korr[0] + " y : " + korr[1]); 
}

方法二:监听ViewTreeObserver的布局完成事件

如果你的TextView位置可能随布局动态变化(比如屏幕旋转、窗口调整),可以用这个监听,它会在整个视图树完成布局时触发,记得拿到位置后移除监听避免重复执行:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_game_layout);
    
    TextView tablojj = findViewById(R.id.tablojj);
    ViewTreeObserver observer = tablojj.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            // 根据API版本移除监听
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                tablojj.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                tablojj.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            konumal();
        }
    });
}

方法三:在onWindowFocusChanged中调用

当Activity获得窗口焦点时,View的布局肯定已经完成了,适合需要在界面完全显示后获取位置的场景:

private boolean isPositionFetched = false; // 标记是否已经获取过位置,避免重复执行

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus && !isPositionFetched) {
        konumal();
        isPositionFetched = true;
    }
}

关于方法选择的补充

你原本用的getLocationInWindow()或者getLocationOnScreen()都是正确的方法,问题完全出在调用时机上:

  • 如果只需要单次获取位置,优先用View.post(),代码最简洁;
  • 如果需要监听布局变化(比如字谜游戏中可能有动态调整布局的需求),用OnGlobalLayoutListener;
  • 如果要在界面完全可见后获取位置,用onWindowFocusChanged。

另外,如果你想获取TextView相对于父布局(比如你的TableLayout)的位置,getLeft()、getTop()同样有效,只要在布局完成后调用就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:31:28