Why is the width and height of the View 0 in the OnCreate () method of the Activity?
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); getViewSize("onCreate");}private void getViewSize(String methodTag) { int width = myview.getWidth(); int height = myview.getHeight(); Log.i(TAG, methodTag + ": width=" + width + " | height=" + height);}
Log as follows:
12-15 17:04:55.470 29286-29286/cn.codingblock.view I/MyViewActivity: onCreate: width=0 | height=0
As shown in the code results above, we try to get the width and height of the control in the activity's OnCreate () method, but we get 0 because View drawing and activity life cycle methods are not synchronized, even if the activity callback OnCreate (), OnStart (), Onresume () method, view is not necessarily synchronized to complete the drawing, so at this point in these methods to obtain the size of the View can not be obtained, the solution has the following:
Method One, the dimensions of the View are obtained in the onwindowfocuschanged () method of the Activity.
在 Activity 中,当对所有的 View 初始化完毕后,会回调 onWindowFocusChanged() 方法。
/** * 方案一 * 当 View 初始化完毕是回调 * 当 Activity 每次获取和失去焦点时回调 * @param hasFocus */@Overridepublic void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); getViewSize("onWindowFocusChanged");}
Method two, use View.post () to post the task to the message queue, when the View initialization is complete looper will perform the task.
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); // 方案二、将任务post到消息队列中,当view初始化完毕后looper会执行任务 myview.post(new Runnable() { @Override public void run() { getViewSize("post"); } });}
Method Three, you can use some of the Viewtreeobserver listening interface.
例如:当 View 树的状态或者 View 树内部的 View 的可见性发生改变时,ViewTreeObserver.OnGlobalLayoutListener 接口的 onGlobalLayout() 会被回调,可以在此方法内部获取 View 的尺寸。
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); // 方案三、当 View 树的状态或者 View 树内部的 View 的可见性发生改变时, // ViewTreeObserver.OnGlobalLayoutListener 接口的 onGlobalLayout() 会被回调, // 可以在此方法内部获取 View 的尺寸 ViewTreeObserver observer = myview.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewSize("onGlobalLayout"); } });}
Of course, in addition to the above methods there will be other methods, such as the use of delay or in the OnCreate () method to manually invoke the measurement method of the View, relative to the above several methods more convenient.
Finally want to say is, this series for Bo master on Android knowledge again comb, check the learning process, on the one hand is forgetting things to review again, on the other hand believe in the process of re-learning will have a huge new harvest, if you also have with me the same idea, may wish to pay attention to my study together , explore each other and make progress together!
Reference documents:
- Explore the art of Android development
- "Android Development advanced from small to expert"
Android Check Trap (view article)--why is the width and height of the view in the Activity's OnCreate () method 0?