Android: Get the object size in onCreate ()
In onCreate (), the View has not been drawn. Many times, we need to execute some code to operate the View when a page is just loaded, we usually place the code in the onCreate () method of Activity or the onCreateView () method of Fragment. However, because the View is not fully drawn when these Hook methods are called, many operations cannot take effect. For example, if you call myButton. getHeight () of a button in onCreate (), the result is always 0. If you don't want to take a long time, you can directly look at the solution in the final conclusion. Button myButton = null; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); myButton = (Button) findViewById (R. id. button1); // try to get the control size int h = myButton in onCreate. getHeight (); Log. I (TAG, "onCreate (): Height =" + h); // when the result is Height = 0 //...} there are many other similar cases. I previously wrote a pull-down refresh ListView. I hope to refresh it immediately after the Fragment is finished and The code is written in onCreateView. The result is that the list is refreshed, but no animation is refreshed from the drop-down list. The author started to think that since the control has not been drawn in onCreate (), the code is written in some lifecycle functions executed later, can the problem be solved? Then, in some common Hook Functions in Actvity, the author tries to obtain the control size and obtains the following results (arranged in the executed order): onCreate (): height = 0 onStart (): Height = 0 onPostCreate (): Height = 0 onResume (): Height = 0 onPostResume (): Height = 0 onAttachedToWindow (): height = 0 onWindowsFocusChanged (): Height = 1845 can be seen until the onWinodwsFocusChanged () function is called, we can get the correct control size. Other Hook functions, including the onPostCreate () and onPostResume () functions described as called after the Activity is fully started, cannot obtain the correct results. Unfortunately, the correct widget size can be obtained in the onWinodwsFocusChanged () function. However, this method only works in Activity, but in Fragment, this method does not take effect. More solutions 1. Use the Hook method provided by ViewTreeObserver. @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); myButton = (Button) findViewById (R. id. button1); // register the method with ViewTreeObserver to obtain the widget size ViewTreeObserver vto = myButton. getViewTreeObserver (); vto. addOnGlobalLayoutListener (new OnGlobalLayoutListener () {public void onGlobalLayout () {int h = myButton. getHeight (); Log. I (TAG, "Height =" + h); // get the correct result // after a successful call, remove the Hook method to prevent repeated calls // removeGlobalOnLayoutListener () method After API 16 does not use // use the new method removeOnGlobalLayoutListener () instead of myButton. getViewTreeObserver (). removeGlobalOnLayoutListener (this );}});//...} this method is called after the onGlobalLayout () method is drawn by the control, so that the correct result can be obtained. This method can also be used in Fragment. 2. use the post () method of View @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_welcome); myButton = (Button) findViewById (R. id. button1); // use myButton's post () method myButton. post (new Runnable () {@ Override public void run () {int h = myButton. getHeight (); Log. I (TAG, "Height =" + h); // get the correct result }});//...} this method is also applicable to Fragment. The best solution I found before. Note: The Runnable registered by calling the post () method of the measurement object is always called after the object is fully drawn, so the correct result can be obtained. However, using new Handler (). post (mRunnabel) directly in onCreate () does not produce correct results. In many tutorials, the Runnable for actual measurement is called by delay of one millisecond, namely new Handler (). postDelayed (mRunnabel, 500. Although the results can be obtained correctly, it is obviously not a good solution: a small number of milliseconds cannot ensure that the control is drawn. A large number of milliseconds can seriously damage the user's operation experience.