Saving MapFragment (Maps v2) State in Android
Asked Answered
B

2

18

I'm working with the new GoogleMaps API (v2) and have some problems with the fragment. I have two fragments in my app (Map, List) and the user can switch between them. Works fine so far with this code:

if (itemPosition == 0) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragmentpos, myMapFragment).commit();
    } else if (itemPosition == 1) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragmentpos, myListFragment).commit();
}......

When I work with the map, switch to the list fragment and then back to the map fragment, the last position of the map is not saved. This is not what i want, i want that the map is in the save state as i "left" it.. How can I accomplish this? I tried to save the camera position in

public void onSaveInstanceState(Bundle outState){
   outState.putDouble("LAT", mMap.getCameraPosition().target.latitude);
   outState.putDouble("LON", mMap.getCameraPosition().target.longitude);
   outState.putFloat("BEAR", mMap.getCameraPosition().bearing);
   ...

}

and restore it in onCreateView(), but the Bundle is always null. The onSaveInstanceState is not called if I replace the fragments.

So how can I save the state of the map?

Brood answered 1/1, 2013 at 21:28 Comment(1)
can you please have a look at my question and let me know where I am going wrong.. here is my question - #14124854Photoreceptor
S
17

How can I accomplish this?

If you replace() a fragment, the old fragment's views are destroyed, which takes out your MapView and, presumably, the CameraPosition.

onSaveInstanceState() is mostly for configuration changes, such as screen rotations. MapFragment and SupportMapFragment already retain the CameraPosition (which, BTW, is Parcelable, so you can save the whole object in the Bundle rather than piecemeal).

You could consider using show() and hide() instead of replace(), so the fragment and its views sticks around.

Shatterproof answered 1/1, 2013 at 21:35 Comment(7)
I rant into trouble using show() and hide() with two mapfragments. The first mapfragment loads properly, and I can interact with it. However when I switch the tab, the second mapfragment shows the same map view as the first, and its controls don't control the view. When I switch back to the first mapfragment, the controls start working again. I am assuming the second mapfragment is using the first one's surface view for some reason. Any clues as to how can I solve this?Photocell
@basilisk: Off the top of my head, no. Sorry!Shatterproof
Thanks for the quick reply. I'll keep at it and report back if I find anything.Photocell
What I am sure of is its the view, because the zoom controls on the second fragment activate and deactivate just as they are supposed to (zoom out button starts deactivated, and activates once I click the zoom in button, and again deactivates when I click on the zoom out button).Photocell
I have been having the same problem with the mapfragment not showing and hiding properly when using multiple map fragments. Ill post if i fins a solution to that problem but maybe it should be in another question focusing on this.Cygnus
here the same problem. When I use show() and hide(), it works fine, but when I kill the app, my app gets stunned or blocked, and I only can go back or using actionbar controls, because map controls doesn't work properly... PS: I use MapFragment + ListFragmentNavigate
#15117036Navigate
C
0

I solved this problem by holding on to a reference to the CameraPosition on the map in the onDestroyView() method of the fragment; then using that CameraPosition when reinstatiating the map.

The context of my solution has it's own quirks, but essentially I have a map fragment nested within another fragment (which I'm hanging on to, even after it get's replaced). So this is the code in the parent fragment's onActivityCreated() method:

    GoogleMapOptions mapOptions = new GoogleMapOptions();
    if(_savedCameraPosition != null)
    {
        mapOptions.camera(_savedCameraPosition);
    }
    else
    {
        // Centre on Australia
        mapOptions.camera(CameraPosition.fromLatLngZoom(new LatLng(-24.25, 133.25), 15));
    }
    _mapFragment = new SupportMapFragment().newInstance(mapOptions);

    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.map_holder, _mapFragment);
    fragmentTransaction.commit();

Then later in the same class I have:

@Override
public void onDestroyView()
{
    super.onDestroyView();
    _savedCameraPosition = _map.getCameraPosition();
}
Copulative answered 21/2, 2013 at 9:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.