Error opening SupportMapFragment for second time
Asked Answered
B

11

55

When opening my SupportMapFragment (Android maps v2) for a second time (calling setContentView) I get the following error:

01-28 16:27:21.374: E/AndroidRuntime(32743): FATAL EXCEPTION: main
01-28 16:27:21.374: E/AndroidRuntime(32743): android.view.InflateException: Binary XML file line #6: Error inflating class fragment
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.View.inflate(View.java:16119)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at mypackage.MyView.<init>(HitsView.java:26)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at mypackage.MenuListFragment.onItemClick(MenuListFragment.java:133)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView.performItemClick(AbsListView.java:1086)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2855)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.widget.AbsListView$1.run(AbsListView.java:3529)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Handler.handleCallback(Handler.java:615)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.os.Looper.loop(Looper.java:137)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.app.ActivityThread.main(ActivityThread.java:4745)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at java.lang.reflect.Method.invokeNative(Native Method)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at java.lang.reflect.Method.invoke(Method.java:511)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at dalvik.system.NativeStart.main(Native Method)
01-28 16:27:21.374: E/AndroidRuntime(32743): Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f04003b, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
01-28 16:27:21.374: E/AndroidRuntime(32743):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
01-28 16:27:21.374: E/AndroidRuntime(32743):    ... 20 more

The XML file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <fragment
        android:id="@+id/hits_map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.google.android.gms.maps.SupportMapFragment"
        map:mapType="normal"
        map:uiZoomControls="false"
        map:uiZoomGestures="true"
        map:cameraZoom="13"
        map:uiRotateGestures="true"
        map:uiTiltGestures="true"/>
</RelativeLayout>

MyView.class:

public class MyView extends RelativeLayout {
    private GoogleMap map;

    public MyView(Context context, FragmentActivity activity) {
        super(context);
        inflate(activity, R.layout.activity_hits, this);
        this.map = ((SupportMapFragment) activity.getSupportFragmentManager()
            .findFragmentById(R.id.hits_map)).getMap();
    }
}

I have no idea what this error means. Can someone explain this?

Baliol answered 28/1, 2013 at 15:34 Comment(7)
Do you have a View trying to inflate a layout containing a fragment? If so, why?Dacosta
I am. This is not the right way to use it? I am using SlidingMenu. In their docs they say setContentView needs to be called to show the main view. And the main view in this case is a view containing a fragment. link: github.com/jfeinstein10/SlidingMenu#simple-exampleBaliol
I certainly would never do that.Dacosta
Did you eventually solve it?Extinguish
I used the MapView instead, I actually did not know there was a MapView as well.Baliol
[This is a link that will help you, I was getting the same problem but this worked for me :)][1] [1]: #14084450Compatriot
I think this is the best solution: https://mcmap.net/q/94870/-supportmapfragment-on-a-tab-i-can-only-see-onceTehee
S
51

Instead of declaring de SupportMapFragment in layout, do it programatically and be sure you use getChildFragmentMananger instead of the classic getFragmentManager() to create the fragment.

  mMapFragment = SupportMapFragment.newInstance();
    FragmentTransaction fragmentTransaction =
             mMapFragment.getChildFragmentManager().beginTransaction();
     fragmentTransaction.add(R.id.map_root, mMapFragment);
     fragmentTransaction.commit(); 

Keep this SupportMapFragment mMapFragment as you will need it to retrieve the GoogleMap object:

  GoogleMap map = mMapFragment.getMap();
Subarid answered 4/2, 2013 at 15:56 Comment(2)
Yes, you need to wait for a run before the map gets initialised. I use a delay handler to grab a reference to the map after 10 milliseconds, alternatively use the lifecycle to your advantage. i.e. commit the fragment in onCreate and then grab a reference to the map in onResume.Crop
@Subarid , you should use getMapAsync() instead. MapFragmentProrate
M
83

Update: As an alternative solution (which I think is much better) you can use a MapView which is described: here

I ran across a similar problem while working with a tabs implementation. With Google Maps V2, you are stuck with the SupportMapFragment, so using the MapView isn't an option. Between juanmeanwhile's post and comment #1 found here (https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1), I managed to figure out what I was doing wrong.

So, for anyone else getting the Duplicate id error, make sure you declare the fragment programatically, not in XML. This probably means nesting layouts.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="match_parent" >

<!-- Lots of fancy layout -->   

<RelativeLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </RelativeLayout>
</RelativeLayout>

Then you need to create your fragment programatically, but it needs to be done carefully with consideration for the Fragments lifecycle (http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager()). To ensure everything is created at the right time, your code should look like this (taken from comment #1).

public class MyFragment extends Fragment {

private SupportMapFragment fragment;
private GoogleMap map;

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

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
    if (fragment == null) {
        fragment = SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.map, fragment).commit();
    }
}

@Override
public void onResume() {
    super.onResume();
    if (map == null) {
        map = fragment.getMap();
        map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
    }
}
}

Hopefully this saves some time.

Mendie answered 4/4, 2013 at 13:47 Comment(9)
Will this retain the maps instance across all fragments? Or will it be destroyed after onPause()?Roa
FYI you're not stuck with SupportMapFragment, MapView still exists and is fully functional: developers.google.com/maps/documentation/android/reference/com/…Placative
I think if you are using a Fragment you are in-fact stuck with MapFragment, and really SupportMapFragment if you want to support Honeycomb. If you are using an Activity, this is not the case and you can use a MapView (although I have no personally confirmed this). So, in my example, you are basically stuck with that implementation. If you were to use an Activity, you could use the MapView but you would still need to manage the life cycle.Mendie
It does not solve the problem.It still crashes when i run it again.Shinto
@Mendie yes, but i fixed it. I tried lots of things, and finally i solve it. But, i really don't get how i fixed that.Shinto
@Kaleb, thanks for idea. But really, I think google hate all of us.Vanettavang
The code generates an error, which has been solved here: #15207805 (Markus answer)Tyus
After searching like a crazy over the web, this solution worked for me. Thanks!Cleavable
This also works for me and I think the best, based on the answers I saw myself that doesn't requires a MapView.Pentagon
S
51

Instead of declaring de SupportMapFragment in layout, do it programatically and be sure you use getChildFragmentMananger instead of the classic getFragmentManager() to create the fragment.

  mMapFragment = SupportMapFragment.newInstance();
    FragmentTransaction fragmentTransaction =
             mMapFragment.getChildFragmentManager().beginTransaction();
     fragmentTransaction.add(R.id.map_root, mMapFragment);
     fragmentTransaction.commit(); 

Keep this SupportMapFragment mMapFragment as you will need it to retrieve the GoogleMap object:

  GoogleMap map = mMapFragment.getMap();
Subarid answered 4/2, 2013 at 15:56 Comment(2)
Yes, you need to wait for a run before the map gets initialised. I use a delay handler to grab a reference to the map after 10 milliseconds, alternatively use the lifecycle to your advantage. i.e. commit the fragment in onCreate and then grab a reference to the map in onResume.Crop
@Subarid , you should use getMapAsync() instead. MapFragmentProrate
I
24

I've spend a half day resolving this trouble and only found a workaround. Override your onCreate method in YourFragment class:

public void onCreate(Bundle savedInstanceState) {
    setRetainInstance(true); 
    super.onCreate(savedInstanceState);     
}

And override your onDestroy method:

@Override
public void onDestroyView() {
    super.onDestroyView();
    try {
        SupportMapFragment fragment = (SupportMapFragment) getActivity()
                                          .getSupportFragmentManager().findFragmentById(
                                              R.id.multi_inns_on_map);
        if (fragment != null) getFragmentManager().beginTransaction().remove(fragment).commit();

    } catch (IllegalStateException e) {
        //handle this situation because you are necessary will get 
        //an exception here :-(
    }
}
Isbell answered 19/9, 2013 at 22:5 Comment(7)
This answer lets you define your child fragments in XML layouts, which I find more manageable than having to replace pieces of layout with fragments programmatically.Anastigmatic
please pay attention to exception handling block, because you have risks to loose object's state!! This is why it's called workaroundIsbell
instead if the try-catch block I use if (f != null && f.isResumed()) {}, it works for meScimitar
@Jaroslav: At what stage will I get an exception?Primavera
@Primavera - for instance on display rotation } catch (IllegalStateException e) { //handle this situation because you are necessary will get //an exception here :-( }Isbell
Please use this approach to solve the problem described above. And don't forget to delete setRetainInstance(true) in onCreate method code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1Isbell
It worked for me! Thenk you, this should be the right answer.Midvictorian
D
2

I had passed all this day looking for the solution to this problem, reading all the workaroung here, and I found this way to solve the problems. I will post all the code, because this question lacks a complete answer, just some tiny snippet that does match a full scenario and does help anybody.

public class LocationFragment extends Fragment implements View.OnClickListener {

    private GoogleMap googleMap;
    private static View rootView;
    private SupportMapFragment supportMapFragment;

    public LocationFragment() {
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setRetainInstance(true);
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if(savedInstanceState == null) {

            if (rootView != null) {
                ViewGroup parent = (ViewGroup) rootView.getParent();
                if (parent != null)
                    parent.removeView(rootView);
            }

            try{
                if(rootView == null)
                {
                    rootView = inflater.inflate(R.layout.fragment_location, container, false);
                }

                supportMapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
                LocationUtility locationUtility = LocationUtility.getInstance(context);
                GoogleMap googleMap =  locationUtility.initilizeMap(supportMapFragment);

              //More code

            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        return rootView;
    }

}

By debugging this, you will notice that it does not matter how the fragment operates, you dont need botter for the onDestroyMethod, etc, since the validation of null, just operates with the current instance of the object.

Enjoy! ;)

Duffel answered 29/8, 2014 at 1:7 Comment(1)
Thanks a bunch!! I have been stuck with this issue for over a week. Though I am using Xamarin Android (C#) but your solution worked perfectly!Lodged
F
1

I ran into this issue and found in my android logs that my hardware acceleration was not turned on. After I turned it on in my AndroidManifest I was displaying the maps multiple times was no longer an issue. I was using an x86 emulator.

Fugazy answered 12/9, 2013 at 4:49 Comment(0)
S
1

After lot of Hit and tries and I finally manage to use MapView Fragment perfactly in my App and result looks like this :-

enter image description here

, here is my MapView Fragment Class :-

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.serveroverload.yago.R;


public class HomeFragment extends Fragment implements LocationListener {
    // Class to do operations on the Map
    GoogleMap googleMap;
    private LocationManager locationManager;

    public static Fragment newInstance() {
        return new HomeFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.home_fragment, container, false);
        Bundle bdl = getArguments();

        // setuping locatiomanager to perfrom location related operations
        locationManager = (LocationManager) getActivity().getSystemService(
                Context.LOCATION_SERVICE);

        // Requesting locationmanager for location updates
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, 1, 1, this);

        // To get map from MapFragment from layout
        googleMap = ((MapFragment) getActivity().getFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        // To change the map type to Satellite
        // googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

        // To show our current location in the map with dot
        // googleMap.setMyLocationEnabled(true);

        // To listen action whenever we click on the map
        googleMap.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public void onMapClick(LatLng latLng) {
                /*
                 * LatLng:Class will give us selected position lattigude and
                 * longitude values
                 */
                Toast.makeText(getActivity(), latLng.toString(),
                        Toast.LENGTH_LONG).show();
            }
        });

        changeMapMode(3);

        // googleMap.setSatellite(true);
        googleMap.setTrafficEnabled(true);
        googleMap.setBuildingsEnabled(true);
        googleMap.setMyLocationEnabled(true);

        return v;
    }

    private void doZoom() {
        if (googleMap != null) {
            googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(18.520430, 73.856744), 17));
        }
    }

    private void changeMapMode(int mapMode) {

        if (googleMap != null) {
            switch (mapMode) {
            case 0:
                googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);
                break;

            case 1:
                googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;

            case 2:
                googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;

            case 3:
                googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;

            case 4:
                googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;

            default:
                break;
            }
        }
    }

    private void createMarker(double latitude, double longitude) {
        // double latitude = 17.385044;
        // double longitude = 78.486671;

        // lets place some 10 random markers
        for (int i = 0; i < 10; i++) {
            // random latitude and logitude
            double[] randomLocation = createRandLocation(latitude, longitude);

            // Adding a marker
            MarkerOptions marker = new MarkerOptions().position(
                    new LatLng(randomLocation[0], randomLocation[1])).title(
                    "Hello Maps " + i);

            Log.e("Random", "> " + randomLocation[0] + ", " + randomLocation[1]);

            // changing marker color
            if (i == 0)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
            if (i == 1)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            if (i == 2)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_CYAN));
            if (i == 3)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
            if (i == 4)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            if (i == 5)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
            if (i == 6)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED));
            if (i == 7)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
            if (i == 8)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
            if (i == 9)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));

            googleMap.addMarker(marker);

            // Move the camera to last position with a zoom level
            if (i == 9) {
                CameraPosition cameraPosition = new CameraPosition.Builder()
                        .target(new LatLng(randomLocation[0], randomLocation[1]))
                        .zoom(15).build();

                googleMap.animateCamera(CameraUpdateFactory
                        .newCameraPosition(cameraPosition));
            }
        }

    }

    /*
     * creating random postion around a location for testing purpose only
     */
    private double[] createRandLocation(double latitude, double longitude) {

        return new double[] { latitude + ((Math.random() - 0.5) / 500),
                longitude + ((Math.random() - 0.5) / 500),
                150 + ((Math.random() - 0.5) * 10) };
    }

    @Override
    public void onLocationChanged(Location location) {

        if (null != googleMap) {
            // To get lattitude value from location object
            double latti = location.getLatitude();
            // To get longitude value from location object
            double longi = location.getLongitude();

            // To hold lattitude and longitude values
            LatLng position = new LatLng(latti, longi);

            createMarker(latti, longi);

            // Creating object to pass our current location to the map
            MarkerOptions markerOptions = new MarkerOptions();
            // To store current location in the markeroptions object
            markerOptions.position(position);

            // Zooming to our current location with zoom level 17.0f
            googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,
                    17f));

            // adding markeroptions class object to the map to show our current
            // location in the map with help of default marker
            googleMap.addMarker(markerOptions);
        }

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onDestroyView() {
        // TODO Auto-generated method stub
        super.onDestroyView();

        locationManager.removeUpdates(this);

        android.app.Fragment fragment = getActivity().getFragmentManager()
                .findFragmentById(R.id.map);
        if (null != fragment) {
            android.app.FragmentTransaction ft = getActivity()
                    .getFragmentManager().beginTransaction();
            ft.remove(fragment);
            ft.commit();
        }
    }


}

My Xml file looks like this:-

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.MapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Most Important thing to note is that DO Not Mix app.Fragment with v4.Fragments else app will crash badly.

As you can see I have used app.Fragment to attach and remove my MapView Fragment

Hope it will help Somebody

Scape answered 18/12, 2015 at 2:46 Comment(1)
Have you managed to add "My location" button in the mapView? and also highlight the current user location in real time?Meanwhile
M
1

I tried various solutions proposed here, and the best one IMHO is the MapView. Anyway, I found another solution that could suit your needs (or maybe not).

I had my SupportMapFragment inside a ViewPager+FragmentPagerAdapter with 3 tabs. So I just configured the ViewPager in a way that it never destroys the tab where the SupportMapFragment is.

viewPager.setOffScreenPageLimit(2);
viewPager.setAdapter(...);

With this call, the ViewPager will always maintain two pages after, and two pages before the current one, so none of my three tabs is never destroyed/recreated.

Problem solved :)

Note that memory consumption will increase

Meanwhile answered 19/8, 2016 at 7:56 Comment(1)
thanks a lot. I have view pager with 3 fragments, and this was exactly what i needCarducci
S
0
private MainActivity mainActObj;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mainActObj = getMainActivity();
}

@SuppressWarnings("unchecked")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    if (mainActObj.mapView == null) {
        return mainActObj.mapView = inflater.inflate(R.layout.fragment_map,
                null);
    }

    else {
        ViewGroup parent = (ViewGroup) mainActObj.mapView.getParent();
        if (parent != null) {
            parent.removeView(mainActObj.mapView);
        }

        try {
            return mainActObj.mapView = inflater.inflate(
                    R.layout.fragment_map, container, false);
        } catch (InflateException except) {
            return mainActObj.mapView;
        }
    }

}
Sardius answered 2/9, 2014 at 18:10 Comment(0)
C
0

try this code

  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
         finder = new LocationFinder(getActivity());

             view = inflater.inflate(R.layout.fragment_secondfragement, container, false);



                        initMap();

        
      //  getLocation();
        return view;

    }


    public void initMap(){

        if (map == null) {
            mapFragment = (SupportMapFragment) getChildFragmentManager()
                    .findFragmentById(R.id.map);
        }

        map = mapFragment.getMap();
        map.setMyLocationEnabled(true);
        map.getUiSettings().setMyLocationButtonEnabled(true);

    }
Cheremkhovo answered 9/1, 2015 at 9:41 Comment(0)
C
0

I have the same issue and solved by creating google map dynamically. What you have to do is making a class which is extending SupportMapFragment class.

This methods works on gingerbread to lollipop and on nested fragments because it will create the map dynamically so don't have to worry about removing the fragment or anything like that.

Step1:

public class DynamicMapFragment extends SupportMapFragment {

    public GoogleMap googleMap;
    public View mOriginalContentView;
    public static int statusGooglePlayService;    

    @Override
    public void onCreate(Bundle arg0) {
        super.onCreate(arg0);
    }

    @Override
    public View onCreateView(LayoutInflater mInflater, ViewGroup parent,
            Bundle arg2) {

        mOriginalContentView = super.onCreateView(mInflater, parent, arg2);

       //this is for getting height of the phone screen
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay()
                .getMetrics(displaymetrics);
        int height = displaymetrics.heightPixels;

        //Here you can define the height of the map as you desire
        FrameLayout.LayoutParams parentLayout = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT, height / 3);

        mOriginalContentView.setLayoutParams(parentLayout);
        return mOriginalContentView;
    }

    @Override
    public View getView() {
        return mOriginalContentView;
    }

    @Override
    public void onInflate(Activity arg0, AttributeSet arg1, Bundle arg2) {
        super.onInflate(arg0, arg1, arg2);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        googleMap = getMap();

        statusGooglePlayService = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getActivity());
        if (statusGooglePlayService == ConnectionResult.SUCCESS) {
            if (googleMap != null) {
                // do whatever you want to do with map
            }
        } else {
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
                    statusGooglePlayService, getActivity(), -1);
            dialog.show();
        }
    }

}

Then call the above created class from Activity, Fragment like this:

Step2:

//Calling the method from a fragment
private void createMap(View rootView) {
        FrameLayout mapLayout = (FrameLayout)rootView.findViewById(R.id.location_map);
        FragmentTransaction mTransaction = getActivity()
                .getSupportFragmentManager().beginTransaction();
        SupportMapFragment mFRaFragment = new DynamicMapFragment();
        mTransaction.add(mapLayout.getId(), mFRaFragment);
        mTransaction.commit();

        try {
            MapsInitializer.initialize(activity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

XML layout for fragment where you have to add Framelayout instead of a fragment for map

Step3:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >



    <FrameLayout
        android:id="@+id/location_map"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_weight="0" />

      <!--  You can add any other view also whatever you want to add 

      <Button
        android:layout_width="match_parent"
        android:layout_height=""wrap_content""
        android:layout_weight="0" />    -->

</LinearLayout>
Christopherchristopherso answered 14/8, 2015 at 7:10 Comment(1)
Hi, can you have a look on my problem, Its similar to what you explained, but not working for me. will be a great favor. Here is the link:-- #32240638Featherston
E
0

just put on onCreateView

if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }

view = inflater.inflate(R.layout.map, container, false);
Expendable answered 3/11, 2015 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.