在应用程序生命周期中,什么时候可以/应该使用布局测量?

关于这个问题有很多问题,但是大多数都是专门回答我的问题的。

我有一个GoogleMap ,我告诉它适合其相机的某些边界。 也许不是很奇怪,我得到一个错误:

java.lang.IllegalStateException: Map size should not be 0. Most likely, layout has not yet occured for the map view.

所以让我们把这个问题抽象到任何View

这个“布局”事件何时实际发生? onMeasure()不会显示在Activity的生命周期中 。 什么时候可以安全地调用我的布局需要的方法?

Solutions Collecting From Web of "在应用程序生命周期中,什么时候可以/应该使用布局测量?"

正如文件所说,你应该使用这个

 mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), this.getResources().getDisplayMetrics().widthPixels, this.getResources().getDisplayMetrics().heightPixels, 50)); 

这是一个活动,而是

 mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 50)); 

这对我有用。

文档

注意:只有使用更简单的方法newLatLngBounds(boundary,padding)才能在地图布局完成后用于移动摄像机,以生成CameraUpdate。 在布局过程中,API会计算正确投影边界框所需的地图显示边界。 相比之下,甚至在地图布局之前,您可以随时使用由更复杂的方法newLatLngBounds(边界,宽度,高度,填充)返回的CameraUpdate,因为API会根据您传递的参数计算显示边界。

编辑:

要解决更新的Maps API中的特定问题,您应该使用

 map.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 50)); 

对于任何其他视图和旧的Maps API

使用ViewTreeObserver.OnGlobalLayoutListener就像Simon的回答一样。

你也可以使用View.post()添加一些东西到View消息队列,但我不知道布局是否保证发生在它的末尾(有人说这不是,但即使Groupon + Google做错了 )。

对于地图片段:

 MapFragment.getView().post(new Runnable(){ run() { ...Use the layout params... } } 

我认为你的意思是在UI显示之后做些事情。

使用全局布局侦听器对我来说一直效果不错。 它还具有能够在布局改变时重新评估事物的优点,例如,如果设置了View.GONE或者子视图被添加/移除。

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); // set a global layout listener which will be called when the layout pass is completed and the view is drawn mainLayout.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { // at this point, the UI is fully displayed } } ); setContentView(mainLayout); 

http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html

我会使用onWindowFocusChanged(布尔) 。 只要检查活动的窗口是否得到了重点

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if( hasFocus ) { // Ask for any view size here } }