为何TextView.getHeight()返回值不一致?Android开发技术咨询
问题分析与解决方案
这个问题我之前开发Android时也踩过坑!核心原因是Android的视图绘制流程和Activity生命周期不同步:
在onCreate、onResume、onPostResume这些生命周期方法执行时,你的TextView虽然已经被初始化,但系统还没完成它的**测量(measure)和布局(layout)**步骤,这时候调用getHeight()自然返回0。而用户点击按钮时,界面已经完全绘制渲染完成,视图的尺寸已经确定,所以能拿到正确的864。
下面给你几个靠谱的解决方案,按需选择:
方案1:用ViewTreeObserver监听布局完成
通过ViewTreeObserver的OnGlobalLayoutListener,可以监听视图树的布局完成事件,这时候就能安全获取视图高度了:
TextView text; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (AutoScrollingText) findViewById(R.id.text); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); // 添加布局监听 text.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听,避免重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { text.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { text.getViewTreeObserver().removeGlobalOnLayoutListener(this); } // 这里可以拿到正确的高度 int height = text.getHeight(); Toast.makeText(MainActivity.this, "text height: " + height, Toast.LENGTH_SHORT).show(); } }); } // 其他生命周期方法和点击事件代码不变...
方案2:重写TextView的onSizeChanged方法
如果你的AutoScrollingText是自定义TextView,可以直接重写onSizeChanged方法,这个方法会在视图尺寸确定(包括第一次布局)时被调用:
public class AutoScrollingText extends TextView { // 构造方法省略... @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // h就是当前TextView的高度 if (h > 0) { // 在这里处理高度相关逻辑,比如通知Activity // 可以通过接口回调或者其他方式传递高度值 } } }
方案3:用View.post()延迟执行
利用View.post()把获取高度的代码放到UI线程的消息队列末尾,等视图绘制完成后再执行:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (AutoScrollingText) findViewById(R.id.text); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); text.post(new Runnable() { @Override public void run() { int height = text.getHeight(); Toast.makeText(MainActivity.this, "text height: " + height, Toast.LENGTH_SHORT).show(); } }); }
这三个方案都能解决你的问题,其中方案1和3适合在Activity中快速实现,方案2更适合自定义View的场景。
内容的提问来源于stack exchange,提问作者Admond
相关产品推荐
相关产品推荐

