android在onCreate()方法中获取View的宽度与高度的方法实战

大家好,这篇博文主要是教给大家一个方法,如何在onCreate()方法中获取我们所需的View对象的高度和宽度,大家应该都试验过,在onCreate()方法中通过view.getWidth()方法和view.getHeight()方法得到的结果都是0,那么这是为什么呢?

因为当onCreate()方法被调用时,会调用LayoutInflater将布局文件填充到ContentView。填充过程只包括创建视图,却不包括设置其大小。那么,视图的大小在什么时候指定的呢?

Android开发文档的解释如下:

”绘制由两个遍历过程组成:测量过程和布局过程。测量过程由measure(int,int)方法完成,该方法从上到下遍历视图树。在递归遍历过程中,每个视图都会向下层传递尺寸和规格。当measure方法遍历完成时,每个视图都保存了各自的尺寸信息。第二个过程由layout(int,int,int,int)方法完成,该方法也是从上到下遍历视图树,在遍历过程中,每个父视图通过测量过程的结果定位所有子视图的位置信息。“

  • 结论如下:

只有在整个布局绘制完成后,视图才能得到自身的宽和高,这个过程发生在onCreate()方法之后,因此,在此之前调用getWidth()和getHeight()方法返回的结果都是0。


那么我们怎么在onCreate()方法中得到view的宽和高呢?

当然我们是有方法的,那就是通过View的post()方法解决上述问题,该方法接收一个Runnable线程参数,并将其添加到消息队列中,有趣的是Runnable线程会在UI线程中执行。

示例代码和运行log结果如下所示:

public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      mTextView = (TextView) findViewById(R.id.main_clock_time);
      Log.e(TAG, "mtextview width is : "+mTextView.getWidth()+", height is : "+mTextView.getHeight() );
      mTextView.post(new Runnable() {
          @Override
          public void run() {
            Log.e(TAG, "mtextview width is : "+mTextView.getWidth()+", height is : "+mTextView.getHeight() );
          }
      });
 }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

运行结果:

10-26 14:10:40.109 11697-11697/? E/MainActivity: mtextview width is : 0, height is : 0
10-26 14:10:40.149 11697-11697/? E/MainActivity: mtextview width is : 872, height is : 211

可以看到在post方法之前获取到的结果值如我们之前提到的都是0,但是通过post()方法运行在线程中的就能正确的获取到宽和高了。

那我就当然点进去看了看源码咯,View.Java中的post()方法源码如下:

public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }

        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

然后再进入到post(action)方法中,进入到了HandlerActionQueue.java源码中,可以看到post方法源码如下:

public void post(Runnable action) {
        postDelayed(action, 0);
    }

    public void postDelayed(Runnable action, long delayMillis) {
        final HandlerAction handlerAction = new HandlerAction(action, delayMillis);

        synchronized (this) {
            if (mActions == null) {
                mActions = new HandlerAction[4];
            }
            mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
            mCount++;
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可以看到代码也是做了postDelay的处理延时发送消息,所以这才是能正确的获取到宽和高的终极地方了吧。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值