简述为什么onCreate获取不到View的宽高 ?

参考回答:

onCreate()方法中,获取不到View的宽高是因为View还没有完成测量和布局过程。onCreate()是在ActivityFragment创建时调用的,此时UI元素还没有被完全布局和渲染,宽高信息尚未确定。获取宽高的正确时机是在ViewonLayout()onWindowFocusChanged()等方法中。

详细讲解与拓展:

1. onCreate()生命周期的时机

onCreate()Activity生命周期中的第一个方法,它在Activity创建时调用,负责初始化界面和其他资源。在onCreate()方法中,View对象已经被创建并与XML布局文件绑定,但此时还没有进行测量(measure())和布局(layout())的过程,因此View的宽高还未确定。

2. View的布局流程

在Android中,View的大小是由测量和布局过程决定的。通常包括以下几个步骤:
测量measure()):在此阶段,View根据父视图的MeasureSpec(即宽高约束)来计算自己的大小。
布局layout()):View根据测量结果决定自己在父视图中的位置。
绘制draw()):根据布局信息,View被绘制在屏幕上。

这些步骤通常发生在onLayout()方法之后,onCreate()方法是在这个过程之前调用的,因此View的宽高尚未计算完毕。

3. 为什么在onCreate()中获取不到宽高

  • 测量和布局还未完成:在onCreate()时,View的测量和布局过程尚未执行,因此它的宽高未被确定。宽高的计算是在onLayout()方法或其他生命周期方法中完成的。
  • View的宽高依赖于父布局View的宽高在布局过程中是由父容器根据其LayoutParams和测量模式来确定的。在onCreate()时,父布局尚未完成测量和布局,因此子View的宽高无法得知。

4. 正确的时机获取View的宽高

要获取View的宽高,应该在布局过程完成后,通常在以下几个时机点:
onLayout()方法:此方法在布局过程完成后调用,此时可以获取View的确切位置和大小。

“`java
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int width = getWidth();
int height = getHeight();
}
“`

  • onWindowFocusChanged():当Activity的窗口大小或焦点变化时调用,这时可以安全地获取View的宽高。
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
      super.onWindowFocusChanged(hasFocus);
      if (hasFocus) {
          int width = myView.getWidth();
          int height = myView.getHeight();
      }
    }
    
    Java
  • ViewTreeObserver.OnPreDrawListener:这个监听器在布局和绘制之前调用,也可以用来获取View的宽高。
    myView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
      @Override
      public boolean onPreDraw() {
          int width = myView.getWidth();
          int height = myView.getHeight();
          return true;
      }
    });
    
    Java

5. 总结

onCreate()方法中无法获取View的宽高,因为此时View尚未经过测量和布局。获取View宽高的正确时机是在onLayout()onWindowFocusChanged()等方法中,或者使用ViewTreeObserver.OnPreDrawListener来确保获取到正确的尺寸。

发表评论

后才能评论