Solve the 4 ways to get the View's width and Height to 0 in the onCreate() process

Very often when we dynamically create some Views, we need to determine the layout of other views by getting their width and height, but getting the width and height of the view in onCreate() will get 0.view.getWidth() and view. The fundamental reason why getHeight() is 0 is that the control has not yet finished drawing, and you must wait for the system to finish drawing the View before you can get it. This happens when you need to use dynamic layout (using wrap_content or match_parent). Generally speaking, there is no way to obtain the actual width and height of the View in the Activity.onCreate(...) and onResume() methods. Therefore, we have to use a workaround method to get the width and height after the View is drawn. Below are some possible solutions.

1. Listen to Draw/Layout events: ViewTreeObserver

ViewTreeObserver listens to many different interface drawing events. Generally speaking, OnGlobalLayoutListener is where we can get the width and height of the view. The following code in onGlobalLayout will be called after the View completes the Layout process.
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    view.getHeight(); //height is ready
                }
            });
        }
});

But note that this method is called every time the layout of some views changes (for example, a view is set to Invisible), so after you get the width and height you want, remember to remove the onGlobleLayoutListener:
Used when SDK Lvl < 16
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)

Used when SDK Lvl >= 16
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)

2. Add a runnable to the Layout queue: View.post()

This solution is my favorite, but almost no one knows there is such a method. Simply put, just use View.post() a runnable. The methods in the runnable object will be triggered after events such as View's measure and layout. For details, refer to Romain Guy: The

UI event queue processes events in sequence. After setContentView() is called, the event queue will contain a message requesting a re-layout, so anything you post to the queue will be executed after the layout has changed.
final View view=//smth;
...
view.post(new Runnable() {
            @Override
            public void run() {
                view.getHeight(); //height is ready
            }
        });

This method is better than ViewTreeObserver:
1. Your code will only be executed once, and you don't have to disable the Observer after each execution, which is much more worry-free.
2. The syntax is very simple

Reference :
http://stackoverflow.com/a/3602144/774398
http://stackoverflow.com/a/3948036/774398

3. Override View's onLayout method

This method is only useful in certain scenarios , for example, when what you want to implement should be cohesive and modularized in the view as its internal logic, otherwise this solution is very tedious and cumbersome.
view = new View(this) {
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        view.getHeight(); //height is ready
    }
};

Note that the onLayout method will be called many times, so think carefully about what to do in this method, or disable your code after the first execution.



Additional: Get fixed width and height

If the width and height of the view you want to get are fixed, then you can directly use:
1 View.getMeasureWidth()
2 View.getMeasureHeight()

However, it should be noted that the width and height obtained by these two methods may be different from the actual draw. The official documentation explains the different reasons :

View's size is determined by width and height. A View actually has both width and height values.
quote

The first is measure width and measure height. They define how much width and height the view wants to occupy in the parent View (see Layout for details). The measured height and width can be obtained through getMeasuredWidth() and getMeasuredHeight().

The second is width and height, sometimes called drawing width and drawing height. These values ​​define the actual size of the view after it is drawn on the screen and the layout is complete. These values ​​may differ from measure width and height. Width and height can be obtained by getWidth() and getHeight.

Reference link

https://stackoverflow.com/questions/3591784/getwidth-and-getheight-of-view-returns-0/24035591#24035591

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327007403&siteId=291194637