Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading screen until map appears

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.

like image 471
Zartech Avatar asked Apr 16 '26 07:04

Zartech


1 Answers

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.

like image 118
T3KBAU5 Avatar answered Apr 20 '26 02:04

T3KBAU5