Because the View’s measure procedure and the Activity’s lifecycle methods are not executed synchronously. While all are executed in the main line, there is no clear chronology.

1. Activity/View#onWindowFocusChanged

The onWindowFocusChanged() method is called back when the View is initialized.

2. view.post(runnable)

The runnable is posted to the end of the message queue by POST, and the View is initialized by the time Looper calls the runnable().

3. ViewTreeObserver

This is done using the ViewTreeObserver’s numerous callbacks. The View has an instance of the ViewTreeObserver class. It gets this object and then adds OnGlobalLayoutListener to listen when the state of the View tree changes or the visibility of the View inside the View tree changes. The onGlobalLayout() method will be called back, so this is a good time to get the View’s width and height.

protected void onStart(a) {
    super.onStart();
    ViewTreeObserver observer = view.getViewTreeObserver();
    observer.adddOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout(a) {
            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            int width = view.gerMeasureWidth();
            intheight = view.getMeasureHeight(); }}); }Copy the code

4. view.measure(int widthMeasureSpec, int heightMeasureSpec)

Measure the View manually to get the width and height of the View. It depends on the situation.

  • match_parent

Directly give up, can not measure the specific width and height. The reason is that a MeasureSpec needs to know the remaining space of the parent container according to the measure process of the View, so it is theoretically impossible to measure the size of the View.

  • The dp/px

For example, if the width and height are 100px, measure:

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);
Copy the code
  • wrap_content

The following measure:

int widthMeasureSpec = MeasureSpec.makeMeasureSpec((1 << 30) - 1, MeasureSpec.AT_MOST);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec((1 << 30) - 1, MeasureSpec.AT_MOST);
view.measure(widthMeasureSpec, heightMeasureSpec);
Copy the code

Note that (1 << 30) -1, by analyzing the MeasureSpec implementation, you can see that the size of the View is expressed in 30-bit binary, i.e., up to 30 1s (i.e., 2^ 30-1), i.e. (1 << 30) -1, in maximized mode, It makes sense for us to construct a MeasureSpec with the maximum that the View can theoretically support.