There's a lot of questions on this problem, but most are too specialized to answer my question.
I have a GoogleMap
which I tell to fit its camera to certain bounds. Perhaps not very surprisingly, I get an error:
java.lang.IllegalStateException: Map size should not be 0. Most likely, layout has not yet occured for the map view.
So let's abstract this problem to any View
.
When does this 'layout' event actually take place? onMeasure()
doesn't show up in the Activity Lifecycle, for example. When is it safe to call my layout-needing method?
As the documentation says, you should use this
mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(),
this.getResources().getDisplayMetrics().widthPixels,
this.getResources().getDisplayMetrics().heightPixels,
50));
Where this is an activity, Instead
mapa.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(),
50));
This works for me.
The documentation
Note: Only use the simpler method newLatLngBounds(boundary, padding) to generate a CameraUpdate if it is going to be used to move the camera after the map has undergone layout. During layout, the API calculates the display boundaries of the map which are needed to correctly project the bounding box. In comparison, you can use the CameraUpdate returned by the more complex method newLatLngBounds(boundary, width, height, padding) at any time, even before the map has undergone layout, because the API calculates the display boundaries from the arguments that you pass.
To solve this particular problem in the updated Maps API, you should use
map.moveCamera(CameraUpdateFactory.newLatLngBounds(Builder.build(), 50));
For any other view, and older Maps API, use ViewTreeObserver.OnGlobalLayoutListener
like in Simon's answer.
You can also use View.post()
to add something to the View
message queue, but I don't know if layout is guaranteed to have happened at the end of it (some people say it doesn't, but then even Groupon + Google do it wrong).
For a map fragment:
MapFragment.getView().post(new Runnable(){
run() {
...Use the layout params...
}
}
I think you mean do something after the UI is displayed.
Using a global layout listener has always worked well for me. It also has the advantage of being able to remeasure things if the layout is changed, e.g. if something is set to View.GONE or child views are added/removed.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With