144

I am trying to do a tab layout same in Play Store. I got to display the tab layout using a fragments and viewpager from androidhive. However, I can't implement google maps v2 on it. I searched the internet for hours already, but I can't find a tutorial on how to do it. Can some one please show me how?

nbro
  • 15,395
  • 32
  • 113
  • 196
Jeongbebs
  • 4,100
  • 7
  • 34
  • 60
  • 6
    it's funny that I have to go back to the question I asked 3 years ago so I can remember on how to implement it. – Jeongbebs Sep 13 '16 at 07:26
  • There is not much difference between implementing this for `Activity` and `Fragment` once `getChildFragmentManager()` was used. – NecipAllef Nov 06 '16 at 14:29

13 Answers13

346

By using this code we can setup MapView anywhere, inside any ViewPager or Fragment or Activity.

In the latest update of Google for Maps, only MapView is supported for fragments. MapFragment & SupportMapFragment didn't work for me.

Setting up the layout for showing the map in the file location_fragment.xml:

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

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Now, we setup the Java class for showing the map in the file MapViewFragment.java:

public class MapViewFragment extends Fragment {

    MapView mMapView;
    private GoogleMap googleMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.location_fragment, container, false);

        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);

        mMapView.onResume(); // needed to get the map to display immediately

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

        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                googleMap = mMap;

                // For showing a move to my location button
                googleMap.setMyLocationEnabled(true);

                // For dropping a marker at a point on the Map
                LatLng sydney = new LatLng(-34, 151);
                googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));
            
                // For zooming automatically to the location of the marker
                CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            }
        });

        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }
}

Finally you need to get the API Key for your app by registering your app at Google Cloud Console. Register your app as Native Android App.

arshu
  • 11,805
  • 3
  • 23
  • 21
  • 1
    Hi. There is an error on this line " mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.map)).getMap();". It says SupportMapFragment cannot be resolved to a type and there are no suggestions on how to fix it. – Jeongbebs Oct 14 '13 at 06:31
  • Have you added the latest android-support-v4.jar library? Also the MainActivity must extend a FragmentActivity – arshu Oct 14 '13 at 06:37
  • Hey Man, the code is now clean but I encounter an error when changing tabs. Here is the logcat. http://shrib.com/nullfragment – Jeongbebs Oct 14 '13 at 06:38
  • hey men, my app force stops after I exit the app, why is that? – Jeongbebs Oct 14 '13 at 10:03
  • 2
    `` is for Maps V1, not Maps V2. There will be devices in the future that do not have the `com.google.android.maps` firmware library but are perfectly capable of showing Maps V2 maps. Having this line in your manifest will prevent you from running on such devices, and this line is not required for Maps V2 use. For example, the 17 projects at https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2 do not have this `` element and work fine. – CommonsWare Oct 28 '13 at 13:35
  • @CommonsWare : Yes you are right & so I have edited the answer. Yes now it does not require the `"com.google.android.maps"` now the Maps library is in the Google Play Services – arshu Oct 29 '13 at 05:50
  • @user1519069 : Please post your xml. – arshu Nov 25 '13 at 04:45
  • make sure that you are using android.support.v4.app.Fragment – zacharia Apr 14 '14 at 07:54
  • @Arshu I really liked your way to attach the map fragment. But I have a little difficulty while adding the same. I am getting null pointer exception when I add view to the view pager. Can you please help ? – Akhilesh Mani Apr 21 '14 at 12:46
  • @AkhileshMani: please post your question with proper error log – arshu Apr 22 '14 at 10:13
  • @Arshu I just want to ask your concern is that the fragment which you have made above (MAP FRAGMENT), how it can be used as a View Pager Item ? is it possible, if yes can you please suggest me a means to do the same. ?\ – Akhilesh Mani Apr 22 '14 at 10:47
  • @AkhileshMani : For using as a ViewPager item just set it as normal fragment in the ViewPager. For more info refer this link : http://tamsler.blogspot.in/2011/10/android-viewpager-and-fragments.html – arshu Apr 22 '14 at 17:13
  • where is main.xml file ? – ckpatel Jul 19 '14 at 10:05
  • @Go2 : main.xml can be any layout design file. You can also directly add the LocationFragment.class, then you won't need any layout for the MainActivity.class – arshu Jul 21 '14 at 07:50
  • After successful integration of google map i have got a problem and the problem is when i try to close the app clicking back button the app shows a Unfortunately app has stopped.. < – user2273146 Oct 24 '14 at 02:01
  • @user2273146: u can paste the crash log at some site & then put the link here. So that i can help u by seeing the log file. – arshu Oct 24 '14 at 07:11
  • @NewDeveloper : you can have anything in the main.xml it's not a big deal :) – arshu Nov 23 '14 at 08:19
  • Hi is there any solution to this problem.. android.view.InflateException: Binary XML file line #8: Error inflating class fragment – user2273146 Dec 11 '14 at 05:31
  • Thank you so much @Arshu, I'm almost there. My map displays a blank white space, with the Google logo in the bottom left. Do you know why this might be happening (and not showing the map)? – Azurespot Dec 29 '14 at 04:16
  • @NoniA.: Please check if you have enabled Maps for Android V2 in API Console, then generate an API Key. Check if there is any Authorization failure. – arshu Dec 29 '14 at 05:59
  • Thanks @Arshu, I have been checking everything over again and again, I got my key, enabled V2 in the API Console, put everything I need in the Manifest... I get an Authorization failure in the Logcat (my app does not crash though, so the code must be right). Now I'm starting to think because I renamed my package name a couple of times, that might be part of it. Even though I changed it in the SHA1 code I input in API Console, and I even uninstalled my app from my phone and reran it, but still the same Authorization error and blank map. I'm not sure what there is left to try. :( – Azurespot Dec 29 '14 at 06:40
  • 1
    @NoniA.: Authorization Failure means that the API key you have provided is incorrect. Refer to this link on how to generate the API Key properly: https://developers.google.com/maps/documentation/android/start – arshu Dec 29 '14 at 07:05
  • Thanks @Arshu!!! I must have gone to a Console page that was for my apps in general to get my key (strange) because the Console link from that link you posted sent me to a different looking Console page, specially for my registered project (app). Turns out the key was different! So that one worked. Thanks a million!!! – Azurespot Dec 29 '14 at 07:24
  • I'm missing just one thing: How and where do you add the LocationFragment to the activity? fragmentManager.beginTransaction().add(R.id.layoutToAddFragmentTo, mapFragment).commit(); ? – Kalisky Jan 08 '15 at 14:11
  • 7
    i am getting error while using this method .please help PID: 16260 java.lang.NullPointerException at com.example.imran.maps.MeFragment.setUpMapIfNeeded(MeFragment.java:115) at com.example.imran.maps.MeFragment.onCreateView(MeFragment.java:72) code is here : googleMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.map)).getMap(); – Imran Ahmed Jan 31 '15 at 17:08
  • 7
    I get an errore "NullPointerException" on mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.location_map)).getMap(); – aletede91 Apr 28 '15 at 09:21
  • @Kalisky The layout "" does this for you automatically. – swooby May 17 '15 at 18:42
  • 4
    The example code piece: mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.location_map)).getMap(); will crash in getMap() if findFragmentById() returns null. – Gunnar Forsgren - Mobimation May 26 '15 at 08:24
  • If i want to override onLocationChanged(), where shout i put it and how? – Copacel Nov 11 '16 at 20:38
  • 1
    @CalinCretu Please refer these 2 links to implement Location Updates. https://developer.android.com/training/location/receive-location-updates.html https://developers.google.com/maps/documentation/android-api/location – arshu Nov 14 '16 at 07:18
  • I am using android studio, at `googleMap.setMyLocationEnabled(true);` it's showing me a red line and when i hover over it , it says some `permission checks`, as a newbie i don't know what to do? – Moeez Jan 26 '17 at 13:26
  • @faisal1208 : please check this link: https://developers.google.com/maps/documentation/android-api/start – arshu Jan 29 '17 at 05:43
  • it works.. But my marker click listener not working.. my api request called in onMapReady() and in response i have added markers on map like this MarkerManager networkMarkerManager.addMarker(homeNetworkMarker); . I have set networkMarkerManager.setOnMarkerClickListener(this); in OnMapready. I dont know why marker click listener not working. Its working before above code add. – Vishal Jadav Feb 25 '17 at 07:32
  • 2
    Yeah this doesn't work: `java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bo.o()' on a null object reference` – Peter Weyand Feb 25 '18 at 03:04
  • @HeshamYassin : The sample code here supports fragments for markers. You can find relevant examples in the [link](https://developers.google.com/maps/documentation/android-sdk/map-with-marker) here. – arshu Jun 21 '18 at 05:59
  • compile 'com.google.android.gms:play-services-maps:15.0.1' in Gradle.properties(App) dependencies – Terranology Jun 26 '18 at 17:36
  • Works for me, However it seems that MapsInitializer initialization step is not neccessary https://developers.google.com/android/reference/com/google/android/gms/maps/MapsInitializer – Felix Stanley Mar 06 '22 at 09:01
149

The following approach works for me.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
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;

/**
 * A fragment that launches other parts of the demo application.
 */
public class MapFragment extends Fragment {

MapView mMapView;
private GoogleMap googleMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // inflat and return the layout
    View v = inflater.inflate(R.layout.fragment_location_info, container,
            false);
    mMapView = (MapView) v.findViewById(R.id.mapView);
    mMapView.onCreate(savedInstanceState);

    mMapView.onResume();// needed to get the map to display immediately

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

    googleMap = mMapView.getMap();
    // latitude and longitude
    double latitude = 17.385044;
    double longitude = 78.486671;

    // create marker
    MarkerOptions marker = new MarkerOptions().position(
            new LatLng(latitude, longitude)).title("Hello Maps");

    // Changing marker icon
    marker.icon(BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

    // adding marker
    googleMap.addMarker(marker);
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(17.385044, 78.486671)).zoom(12).build();
    googleMap.animateCamera(CameraUpdateFactory
            .newCameraPosition(cameraPosition));

    // Perform any camera updates here
    return v;
}

@Override
public void onResume() {
    super.onResume();
    mMapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mMapView.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    mMapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mMapView.onLowMemory();
}
}

fragment_location_info.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
nbro
  • 15,395
  • 32
  • 113
  • 196
Brandon Yang
  • 2,380
  • 1
  • 15
  • 6
  • 8
    you are a genius, you saved my life. mMapView.onResume();// needed to get the map to display immediately was the key – Stephane Maarek Nov 11 '14 at 04:28
  • 1
    I keep getting the same error `java.lang.NullPointerException: IBitmapDescriptorFactory is not initialized`. I thought that the try catch would take care of this. Can someone help me out? –  Jul 06 '15 at 18:03
  • @BrandonYang thats is awesome man.. I was able to resolve navigation drawer and map combination very simply... Cheers!! – Sreehari Jan 20 '16 at 08:11
  • @BrandonYang: Do you know why you need to manually call all the lifecycle callbacks for `mMapView`? – Christian Aichinger Jan 24 '16 at 02:13
  • mMapView.onResume(); was the one the most crucial line :D Thanks!! – Gurpreet Mar 12 '16 at 08:21
  • Shows blank map for me. I wonder if it has anything to do with API keys. – matthias_b_nz Apr 28 '16 at 01:16
  • 6
    `getMap()` is deprecated. Use getMapAsync and onMapReadyCallback instead: http://stackoverflow.com/a/31371953/4549776 – jmeinke May 19 '16 at 10:58
  • If i want to override onLocationChanged(), where shout i put it and how? – Copacel Nov 11 '16 at 20:38
  • I am using android studio, at `googleMap.setMyLocationEnabled(true);` it's showing me a red line and when i hover over it , it says some `permission checks`, as a newbie i don't know what to do? – Moeez Jan 26 '17 at 13:27
  • @faisal1208: Since Android 6 (Marshmallow), you have to request permissions at runtime and you can check at runtime, whether your app has the permission or not. [Requesting Permissions at Run Time](https://developer.android.com/training/permissions/requesting.html) – lampenlampen Mar 30 '17 at 17:46
  • Don't we need to add the map API Key? – Faizan Mubasher Dec 20 '17 at 19:24
82

You can use this line if you want to use GoogleMap in a fragment:

<fragment
            android:id="@+id/map"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment" />

GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Maddy Sharma
  • 4,870
  • 2
  • 34
  • 40
51

Latest stuff with getMapAsync instead of the deprecated one.

1. check manifest for

<meta-data android:name="com.google.android.geo.API_KEY" android:value="xxxxxxxxxxxxxxxxxxxxxxxxx"/>

You can get the API Key for your app by registering your app at Google Cloud Console. Register your app as Native Android App

2. in your fragment layout .xml add FrameLayout(not fragment):

                  <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:layout_weight="2"
                android:name="com.google.android.gms.maps.SupportMapFragment"
                android:id="@+id/mapwhere" />

or whatever height you want

3. In onCreateView in your fragment

    private SupportMapFragment mSupportMapFragment; 

    mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere);
    if (mSupportMapFragment == null) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mSupportMapFragment = SupportMapFragment.newInstance();
        fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit();
    }

    if (mSupportMapFragment != null)
    {
        mSupportMapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override public void onMapReady(GoogleMap googleMap) {
                if (googleMap != null) {

                    googleMap.getUiSettings().setAllGesturesEnabled(true);

                      -> marker_latlng // MAKE THIS WHATEVER YOU WANT

                        CameraPosition cameraPosition = new CameraPosition.Builder().target(marker_latlng).zoom(15.0f).build();
                        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
                        googleMap.moveCamera(cameraUpdate);

                }

            }
        });
Piyush
  • 18,895
  • 5
  • 32
  • 63
OWADVL
  • 10,704
  • 7
  • 55
  • 67
  • 3
    Thanks, Save lot of time, this is the correct answer as per today with latest library updates. – Sam Oct 26 '15 at 11:37
  • For me it didn't worked. I spent so much time to notice that, there in layout should be ` – user3448282 Oct 27 '15 at 18:47
  • IMO there is a small but important mistake in the code. There should be FragmentManager fragmentManager = getChildFragmentManager(); instead of getFragmentManager when adding the SupportMapFragment. As the code is now, the map fragment is always added when onCreateView is called (which is bad, since it doesnt keep the map state). Furthermore, I would call getMapAsync only in the branch mSupportmapFragment == null to perform initial settings only once! – user1299412 Dec 27 '15 at 17:33
  • @user1299412 man, you can edit the post, and I'll just update the answer. :) – OWADVL Dec 27 '15 at 21:22
  • When i changed the `SupportMapFragment` into `MapFragment` in the activity, changed the `FrameLayout` into `fragment`in the layout file and and changed the `com.google.android.gms.maps.SupportMapFragment` into `com.google.android.gms.maps.MapFragment` it works fine for me. Before these changes it didn't work. Maybe this helps others.... – CodeNinja Feb 26 '16 at 10:54
  • seems the best answer here without getMap() :-) Try it tomorrow! Thx a lot – Johannes Knust Jun 06 '16 at 21:49
10

here what i did in detail:

From here you can get google map api key

alternative and simple way

first log in to your google account and visit google libraries and select Google Maps Android API

dependency found in android studio default map activity :

compile 'com.google.android.gms:play-services:10.0.1'

put your key into android mainifest file under application like below

in AndroidMainifest.xml make these changes:

    // required permission
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


        // google map api key put under/inside <application></application>
        // android:value="YOUR API KEY"
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="AIzasdfasdf645asd4f847sad5f45asdf7845" />

Fragment code :

public class MainBranchFragment extends Fragment implements OnMapReadyCallback{

private GoogleMap mMap;
    public MainBranchFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view= inflater.inflate(R.layout.fragment_main_branch, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_branch_map);
        mapFragment.getMapAsync(this);
        return view;
    }




     @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
            LatLng UCA = new LatLng(-34, 151);
            mMap.addMarker(new MarkerOptions().position(UCA).title("YOUR TITLE")).showInfoWindow();

            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(UCA,17));

        }
    }

in you fragment xml :

<fragment
                android:id="@+id/main_branch_map"
                android:name="com.google.android.gms.maps.SupportMapFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context="com.googlemap.googlemap.MapsActivity" />
dharmx
  • 694
  • 1
  • 13
  • 20
5

For the issue of getting a NullPointerException when we change the Tabs in a FragmentTabHost you just need to add this code to your class which has the TabHost. I mean the class where you initialize the tabs. This is the code :

/**** Fix for error : Activity has been destroyed, when using Nested tabs 
 * We are actually detaching this tab fragment from the `ChildFragmentManager`
 * so that when this inner tab is viewed back then the fragment is attached again****/

import java.lang.reflect.Field;

@Override
public void onDetach() {
    super.onDetach();
    try {
        Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}
Piyush
  • 18,895
  • 5
  • 32
  • 63
arshu
  • 11,805
  • 3
  • 23
  • 21
4
public class DemoFragment extends Fragment {


MapView mapView;
GoogleMap map;
LatLng CENTER = null;

public LocationManager locationManager;

double longitudeDouble;
double latitudeDouble;

String snippet;
String title;
Location location;
String myAddress;

String LocationId;
String CityName;
String imageURL;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View view = inflater
                .inflate(R.layout.fragment_layout, container, false);

    mapView = (MapView) view.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);

  setMapView();


 }

 private void setMapView() {
    try {
        MapsInitializer.initialize(getActivity());

        switch (GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getActivity())) {
        case ConnectionResult.SUCCESS:
            // Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT)
            // .show();

            // Gets to GoogleMap from the MapView and does initialization
            // stuff
            if (mapView != null) {

                locationManager = ((LocationManager) getActivity()
                        .getSystemService(Context.LOCATION_SERVICE));

                Boolean localBoolean = Boolean.valueOf(locationManager
                        .isProviderEnabled("network"));

                if (localBoolean.booleanValue()) {

                    CENTER = new LatLng(latitude, longitude);

                } else {

                }
                map = mapView.getMap();
                if (map == null) {

                    Log.d("", "Map Fragment Not Found or no Map in it!!");

                }

                map.clear();
                try {
                    map.addMarker(new MarkerOptions().position(CENTER)
                            .title(CityName).snippet(""));
                } catch (Exception e) {
                    e.printStackTrace();
                }

                map.setIndoorEnabled(true);
                map.setMyLocationEnabled(true);
                map.moveCamera(CameraUpdateFactory.zoomTo(5));
                if (CENTER != null) {
                    map.animateCamera(
                            CameraUpdateFactory.newLatLng(CENTER), 1750,
                            null);
                }
                // add circle
                CircleOptions circle = new CircleOptions();
                circle.center(CENTER).fillColor(Color.BLUE).radius(10);
                map.addCircle(circle);
                map.setMapType(GoogleMap.MAP_TYPE_NORMAL);

            }
            break;
        case ConnectionResult.SERVICE_MISSING:

            break;
        case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:

            break;
        default:

        }
    } catch (Exception e) {

    }

}

in fragment_layout

<com.google.android.gms.maps.MapView
                android:id="@+id/mapView"
                android:layout_width="match_parent"
                android:layout_height="160dp"                    
                android:layout_marginRight="10dp" />
Vaishali Sutariya
  • 5,093
  • 30
  • 32
3

When you add yor map use:

getChildFragmentManager().beginTransaction()
    .replace(R.id.menu_map_container, mapFragment, "f" + shabbatIndex).commit();

instead of .add and instead of getFragmentManager.

Ricardo
  • 748
  • 12
  • 26
3

This is the Kotlin way:

In fragment_map.xml you should have:

<?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.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In your MapFragment.kt you should have:

    private fun setupMap() {
        (childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?)!!.getMapAsync(this)
    }

Call setupMap() in onCreateView.

Gilbert
  • 2,699
  • 28
  • 29
1

According to https://developer.android.com/about/versions/android-4.2.html#NestedFragments, you can use nested fragments to achieve this by calling getChildFragmentManager() if you still want to use the Google Maps fragment instead of the view inside your own fragment:

SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.content, mapFragment).commit();

where "content" is the root layout in your fragment (preferably a FrameLayout). The advantage of using a map fragment is that then the map lifecycle is managed automatically by the system.

Although the documentation says "You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically. ", I have somehow successfully done this and it worked fine. Here is my code:
In the fragment's onCreateView() method:

View view = inflater.inflate(R.layout.layout_maps, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(...);

In the layout:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Hope it helps!

Shreck Ye
  • 1,591
  • 2
  • 16
  • 32
1

i just create MapActivity and inflate it to fragment . MapActivity.java:

package com.example.ahmedsamra.mansouratourguideapp;

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_categories);//layout for container
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, new MapFragment())
                .commit();
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng mansoura = new LatLng(31.037933, 31.381523);
        mMap.addMarker(new MarkerOptions().position(mansoura).title("Marker in mansoura"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(mansoura));
    }
}

activity_map.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.ahmedsamra.mansouratourguideapp.MapsActivity" />

MapFragment.java:-

package com.example.ahmedsamra.mansouratourguideapp;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * A simple {@link Fragment} subclass.
 */
public class MapFragment extends Fragment {


    public MapFragment() {
        // Required empty public constructor
    }


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

}
0

I've a workaround for NullPointerException when remove fragment in on DestoryView, Just put your code in onStop() not onDestoryView. It works fine!

@Override
public void onStop() {
    super.onStop();
    if (mMap != null) {
        MainActivity.fragmentManager.beginTransaction()
                .remove(MainActivity.fragmentManager.findFragmentById(R.id.location_map)).commit();
        mMap = null;
    }
}
Piyush
  • 18,895
  • 5
  • 32
  • 63
0

Dynamically adding map fragment to view Pager:

If you are targeting an application earlier than API level 12 make an instance of SupportedMapFragment and add it to your view page adapter.

SupportMapFragment supportMapFragment=SupportMapFragment.newInstance();
        supportMapFragment.getMapAsync(this);

API level 12 or higher support MapFragment objects

MapFragment mMapFragment=MapFragment.newInstance();
            mMapFragment.getMapAsync(this);
Adeeb karim
  • 292
  • 3
  • 9