MapView inside Fragment - specified child already has a parent

柔情痞子 提交于 2019-11-29 03:59:05

I'm not sure if this is the same problem as you were having, but it turns out that inflating is okay, so long as you don't attach to the root.

For example, you need to do something like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.id.my_layout, container, false);
}

If you fail to add that last false argument to the inflate() call, then you will get the IllegalStateException.

I think what is happening is that without the extra false argument, your inflated view tree is attached to the root view (container) and then when the Activity is started, the system attempts to add the view tree to the root again. Hence the error.

After trying a multitude of things, I ended up doing this:

The root view I returned in onCreateView() is created programmatically, not inflated. However, inflating other views and adding them as children to the programmatically-created root view doesn't seem to cause any problems.

Hat's off to anybody out there who can figure out what's behind this odd behavior. Hope this may be useful to others.

EDIT

It's been a while since I revisited this topic, but as I recall, this would not work for me...

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    return inflater.inflate(R.layout.some_layout, container, false);
}

... whereas this would work for me...

private ViewGroup mapContainer;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    mapContainer = new LinearLayout(getActivity());
    return mapContainer;
}

... and later in onActivityCreated() I would get a MapView from the activity and add it as a child of mapContainer. If I wanted other views (like maybe a header above the MapView), I could inflate them separately and add them to mapContainer, as this code snippet shows.

private ViewGroup mapContainer;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    mapContainer = new LinearLayout(getActivity());
    mapContainer.setOrientation(LinearLayout.VERTICAL);
    View headerView = inflater.inflate(R.layout.some_layout, mapContainer, false);
    mapContainer.addView(headerView);
    return mapContainer;
}

This is what worked for me... Whenever I switched fragments I did

if (mapContainer.getChildAt(0) != null){
        mapContainer.removeViewAt(0);
}

I didn't put that in my onDestroy() or onPause() methods. I did that whenever I switched fragments. For some reason my fragment wasn't calling onPause().

In my onResume() method I did

mapContainer.addView(mapView);

and everything works for me. No more IllegalStateExceptions.

[UPDATE] I wrote a little library, mashing all these LocalActivityManager solutions together: https://github.com/coreform/android-tandemactivities

[old post] You should

mapContainer.removeView(mapView);

before you

mapContainer.addView(mapView);

to avoid such an exception.

...as in literally the line before.

OK, followup after comments:

Try this:

if(mapView.getParent() != null) {
    mapContainer.addView(mapView);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!