I'm working on a little Android application which displays a MapFragment with some markers. The thing is I find the time between the app is launched and that the maps appears too long. So I would like to display a ProgressDialog at the beginning and, when the map starts rendering, dismiss the ProgressDialog and display the map.
Until now, I tried it by creating an instance of MapFragment, calling getMapAsync and show the fragment in the onMapReady callback. But it seems that it doesn't work if you don't display the fragment in the onCreate...
That is my code :
public class MyApp extends FragmentActivity implements OnMapReadyCallback
{
private ProgressDialog mLoading;
private MapFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mFragment = MapFragment.newInstance();
mFragment.getMapAsync(this);
// Dosen't work without the line below
// getFragmentManager().beginTransaction().replace(android.R.id.content, mFragment).commit();
mLoading = ProgressDialog.show(this, "Chargement", "", true, false);
}
@Override
public void onMapReady(GoogleMap googleMap)
{
googleMap.setOnMyLocationButtonClickListener(null);
googleMap.setMyLocationEnabled(false);
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
googleMap.getUiSettings().setMapToolbarEnabled(false);
// When map renders entirely, dismiss ProgressDialog and display MapFragment
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback()
{
@Override
public void onMapLoaded()
{
mLoading.dismiss();
getFragmentManager().beginTransaction().replace(android.R.id.content, mFragment).commit();
}
});
// ...
}
I'm a little bit newbie in the Android world that's why I need your help. Tell me if I'm wrong in code or in English please, I'm learning both.
In order to actually get onMapReady callbacks, the map needs to be created. Right now, you're just creating a MapFragment object then doing nothing with it. The loading of the map won't start until you add it to your screen, as you noted in your question. I'm not sure how your layout XML is set up, but the way I did it in my tests was like this:
Layout XML for where you want the Fragment to appear:
<FrameLayout
android:id="@+id/frame_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
In the onCreate:
MapFragment mFragment = MapFragment.newInstance();
getFragmentManager().beginTransaction().add(R.id.frame_map, mFragment).commit();
FrameLayout fl = new FrameLayout(context);
fl.setBackgroundColor(Color.WHITE); //change to whatever color your activity/fragment has set as its background color
fl.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); //cover the whole frame
final int flid = View.generateViewId(); //generate a new View ID. This requires API 17, so if you're supporting lower than that use just a static integer instead
fl.setId(flid);
((FrameLayout) findViewById(R.id.frame_map)).addView(fl);
Then, in your onMapLoaded callback:
((FrameLayout) findViewById(R.id.frame_map)).removeViewInLayout(findViewById(flid));
This will start the Fragment, then cover it with a new FrameLayout that will just have a solid background (there may be a better way of doing this, I just found this quickly). Then, once the loading is done, the covering layout will be removed. Alternatively, since you're covering it with a ProgressDialog anyways, it's probably not be critical that you can't see the map being loaded, but that's just my opinion. Hopfeully this will work as expected!
Edit: First answer didn't work, revised with a new method.
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