You are only allowed to have a single mapview in a mapactivity exception

1,970 views
Skip to first unread message

Avtar Khalsa

unread,
Oct 19, 2011, 4:37:12 AM10/19/11
to Android Compatibility Library for Google Maps - Support
Hi Guys

I just found this library and seem to have a bit of a problem I hope
someone can point me in the right direction on. If I have a fragment
with a mapview in it, and I swap it out for a different fragment, when
I try to swap the first one back, I get a IllegalStateException You
are only allowed to have a single mapview in a mapactivity exception.

I don't have the mapview in the fragment's xml, I actually add it
during the Fragment's onResume method and try to destroy it in the
fragment's onPause method. I would have thought this would account
for the problem, but it doesn't seem to help. Do any of you have a
solution to this?

My onPause method looks like this:

onPause(){
super.onPause();
layout.removeView(mp);
layout.setVisibility(layout.GONE);
mp = null;
}

Any thoughts/help would be greatly appreciated! Thanks in advance!

Avtar

mjqtreble

unread,
Oct 19, 2011, 5:06:01 AM10/19/11
to Android Compatibility Library for Google Maps - Support
The way I did it is:
It sounds like the view is not getting removed. Try adding adding
logging to your functions to see which way round they are being
called:
Log.i("MyFragment", "onPause Called - map removed");
+
Log.i("MyFragment", "onResume Called - map added");

this should shed some light on the situation.

Androi Android

unread,
Oct 19, 2011, 8:31:47 AM10/19/11
to Android Compatibility Library for Google Maps - Support


Even I'm facing similer problem ..
I hv removed view onDestroy.. still it gives same error .. on
onCreateView of my MapFragment classs

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);

mMapViewContainer = inflater.inflate(R.layout.mapdemo, null);
mMapView = (MapView) mMapViewContainer.findViewById(R.id.map);
}

@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
Log.e("D","DESTROY");
((ViewGroup) mMapViewContainer.getParent()).removeView(mMapView);
((ViewGroup)
mMapViewContainer.getParent()).removeView(mMapViewContainer);
mMapView = null;
mMapViewContainer = null;

}

Avtar Khalsa

unread,
Oct 19, 2011, 4:35:30 PM10/19/11
to android-support-v4...@googlegroups.com
Thank you both for the reply. I was able to resolve the problem by managing the mapview from the FragmentActivity. Rather than having the fragment create the mapview as I was, I had it request the pre-instantiated mapview from the activity. I do not think this would work with the mapview in the layout since that will cause the layout inflater to instantiate a new one each time. 

My onResume looks like this:

mp =holder.getMapView();
layout = (LinearLayout) getView().findViewById(R.id.mapholder);
layout.addView(mp);

Hope that helps.

Pete Doyle

unread,
Oct 19, 2011, 5:16:47 PM10/19/11
to android-support-v4...@googlegroups.com
Avtar, good job figuring it out. :)  You are right on all counts - you have to tie the lifecycle of the MapView to that of the MapActivity (which, in our case, FragmentActivity extends).  I also avoided using LayoutInflater for the reasons you mentioned.

I started a sample in the dev-samples branch, based on the Shakespeare example from the android API Demos.  Instead of showing titles in the left pane and body text in the right, it shows a location title in the left pane and a map of the location in the right.  

You can see the approach I took here:

Pete Doyle

unread,
Oct 19, 2011, 7:04:23 PM10/19/11
to android-support-v4...@googlegroups.com
Sorry, to be more clear...

By "tie the lifecycle of the MapView to that of the MapActivity", I mean that the MapView and MapActivity should exist together for the entirety of their existence (to prevent the IllegalStateException mentioned earlier).  That's why the sample ends up creating the MapView in the FragmentActivity (which extends MapActivity), and re-using the MapView it anytime I create a new MapFragment.

Just thought I should clarify considering "lifecycle" has special meaning when considering an Activity.
Message has been deleted

Androi Android

unread,
Oct 20, 2011, 12:47:02 AM10/20/11
to Android Compatibility Library for Google Maps - Support


Your Work helped a lot :)

Pete Doyle

unread,
Oct 20, 2011, 12:49:36 AM10/20/11
to android-support-v4...@googlegroups.com
Sweet :)

Alexey Zakharov

unread,
Oct 31, 2011, 3:12:48 PM10/31/11
to android-support-v4...@googlegroups.com
Avtar. Could you share your full class listing in gist?

Alexey Zakharov

unread,
Oct 31, 2011, 3:20:55 PM10/31/11
to android-support-v4...@googlegroups.com
Hi Pete,

In my application I want to inject map view in different fragments. Mapview size depends on fragment layout. 

For example: First fragment mapview height is 200x200 dp, in the second fragment 100x100 dp.

Is it possible to implement smth like this?

Thanks,
Alexey

Pete Doyle

unread,
Oct 31, 2011, 3:28:53 PM10/31/11
to android-support-v4...@googlegroups.com
Hi Alexey,
Are you hoping to show both mapviews at the same time?  If so, that's not possible AFAICT.  Maybe with some sort of hack using ActivityGroup to host two concurrent MapActivity instances (i.e. not using fragments):

If you want to just have two separate fragments showing different maps (with only one visible at a time), then this is definitely possible by re-using the MapView instance.  Let me know if that's what you're looking for and I can pass on some tips :)

Thanks,
Pete

Alexey Zakharov

unread,
Oct 31, 2011, 11:25:05 PM10/31/11
to android-support-v4...@googlegroups.com
Yes I don't need to show two maps and want to reuse map view instance. I just want to inject it different fragments with different size and position.

Alexey Zakharov

unread,
Nov 1, 2011, 1:09:00 AM11/1/11
to android-support-v4...@googlegroups.com
This is my current approach:

Activity:

 ViewGroup mapViewContainer = (ViewGroup)LayoutInflater.from(this).inflate(R.layout.map_view, null);
        mapView = (MapView) mapViewContainer.findViewById(R.id.map);
        mapViewContainer.removeView(mapView);

Fragment

        this.placehodler = (ViewGroup) view.findViewById(R.id.map_placeholder);

        this.mapView = getParentActivity().getMapView();
        placehodler.addView(this.mapView, 0);

... on fragment pause

placehodler.removeView(mapView);

PS: It is partially based on your example. I don't understand why you are using mapContainer, i think it is useless.

Pete Doyle

unread,
Nov 2, 2011, 10:15:41 PM11/2/11
to android-support-v4...@googlegroups.com
I took a look and you're right that mMapViewContainer isn't necessary.  I ripped the code from another app in which I needed it to insert a view based on the app state.

It sounds like you have everything working?
Thanks,
Pete

Alexey Zakharov

unread,
Nov 2, 2011, 11:23:43 PM11/2/11
to android-support-v4...@googlegroups.com
Yes. It works. You sample provide me main idea. Thanks.

bhanu

unread,
Oct 18, 2012, 9:39:47 AM10/18/12
to android-support-v4...@googlegroups.com
Thank you so much. you links helped a lot to resolve my application map issue
Reply all
Reply to author
Forward
0 new messages