How to put Google Maps V2 on a Fragment using ViewPager
Asked Answered
M

13

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?

Melodrama answered 14/10, 2013 at 3:48 Comment(2)
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.Melodrama
There is not much difference between implementing this for Activity and Fragment once getChildFragmentManager() was used.Jeffersonjeffery
K
348

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.

Kamchatka answered 14/10, 2013 at 6:8 Comment(37)
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.Melodrama
Have you added the latest android-support-v4.jar library? Also the MainActivity must extend a FragmentActivityKamchatka
Hey Man, the code is now clean but I encounter an error when changing tabs. Here is the logcat. shrib.com/nullfragmentMelodrama
hey men, my app force stops after I exit the app, why is that?Melodrama
<uses-library android:name="com.google.android.maps" android:required="true" /> 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 github.com/commonsguy/cw-omnibus/tree/master/MapsV2 do not have this <uses-library> element and work fine.Septi
@Septi : 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 ServicesKamchatka
@user1519069 : Please post your xml.Kamchatka
make sure that you are using android.support.v4.app.FragmentBabarababassu
@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 ?Titfer
@AkhileshMani: please post your question with proper error logKamchatka
@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. ?\Titfer
@AkhileshMani : For using as a ViewPager item just set it as normal fragment in the ViewPager. For more info refer this link : tamsler.blogspot.in/2011/10/…Kamchatka
where is main.xml file ?Hesitate
@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.classKamchatka
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.. <<don't know what is the problem..Xenophanes
@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.Kamchatka
@NewDeveloper : you can have anything in the main.xml it's not a big deal :)Kamchatka
Hi is there any solution to this problem.. android.view.InflateException: Binary XML file line #8: Error inflating class fragmentXenophanes
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)?Horsey
@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.Kamchatka
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. :(Horsey
@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: developers.google.com/maps/documentation/android/startKamchatka
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!!!Horsey
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(); ?Garmaise
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();Sought
I get an errore "NullPointerException" on mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.location_map)).getMap();Brassy
@Garmaise The layout "<fragment ... class="com.google.android.gms.maps.SupportMapFragment" ... />" does this for you automatically.Manassas
The example code piece: mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.location_map)).getMap(); will crash in getMap() if findFragmentById() returns null.Igbo
If i want to override onLocationChanged(), where shout i put it and how?Documentation
@CalinCretu Please refer these 2 links to implement Location Updates. developer.android.com/training/location/… developers.google.com/maps/documentation/android-api/locationKamchatka
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?Shaquitashara
@faisal1208 : please check this link: developers.google.com/maps/documentation/android-api/startKamchatka
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<NetworkMarker> 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.Snaggletooth
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 referenceBolick
@HeshamYassin : The sample code here supports fragments for markers. You can find relevant examples in the link here.Kamchatka
compile 'com.google.android.gms:play-services-maps:15.0.1' in Gradle.properties(App) dependenciesHairpin
Works for me, However it seems that MapsInitializer initialization step is not neccessary developers.google.com/android/reference/com/google/android/gms/…Rebutter
B
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" />
Blindstory answered 3/8, 2014 at 9:6 Comment(11)
you are a genius, you saved my life. mMapView.onResume();// needed to get the map to display immediately was the keyStir
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?Uteutensil
@BrandonYang thats is awesome man.. I was able to resolve navigation drawer and map combination very simply... Cheers!!Veteran
@BrandonYang: Do you know why you need to manually call all the lifecycle callbacks for mMapView?Hardden
mMapView.onResume(); was the one the most crucial line :D Thanks!!Unpeopled
Shows blank map for me. I wonder if it has anything to do with API keys.Diaphane
getMap() is deprecated. Use getMapAsync and onMapReadyCallback instead: https://mcmap.net/q/161110/-replace-getmap-with-getmapasyncWildman
If i want to override onLocationChanged(), where shout i put it and how?Documentation
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?Shaquitashara
@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 TimeZolazoldi
Don't we need to add the map API Key?Bes
H
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();
Hiatus answered 12/11, 2014 at 15:3 Comment(2)
Thank you for answer! all other responses not work with the latest support librariesNestling
is calling a fragment inside a fragment a good practice ? how does this affect app performance and Good software design??Luciferin
C
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);

                }

            }
        });
Connaught answered 19/8, 2015 at 9:34 Comment(6)
Thanks, Save lot of time, this is the correct answer as per today with latest library updates.Catalinacatalo
For me it didn't worked. I spent so much time to notice that, there in layout should be <fragment instead of FrameLayoutJenniejennifer
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!Maurya
@Maurya man, you can edit the post, and I'll just update the answer. :)Connaught
When i changed the SupportMapFragment into MapFragment in the activity, changed the FrameLayout into fragmentin 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....Roscoeroscommon
seems the best answer here without getMap() :-) Try it tomorrow! Thx a lotFrighten
D
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" />
Displume answered 8/2, 2017 at 8:15 Comment(3)
` gMapFragment.getMapAsync` has an unresolved reference on getMapAsync. This doesn't work.Bolick
are you in activity or fragment?Displume
this works! but i am not sure if calling a fragment inside a fragment is a good practice or not! Please adviseLuciferin
K
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);
    }
}
Kamchatka answered 14/10, 2013 at 6:43 Comment(7)
what should I import on the type "Field"? There are many possibilities.Melodrama
should I send you my project? and then maybe tell me what to do?Melodrama
project sent to your email.Melodrama
yo have not added the google-play-service.jar to your project & also you need to change the project.properties from "target=android-18" to "target=Google Inc.:Google APIs:18"Kamchatka
let us continue this discussion in chatKamchatka
it still force stops. :(Melodrama
This bug is being tracked in the Android Open Source issue tracker: code.google.com/p/android/issues/detail?id=42601Concrescence
D
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" />
Deathwatch answered 7/7, 2014 at 12:12 Comment(2)
is there a way to move the map fragment behind an another fragment eg. menu fragment? It is somehow refreshing and sending my menu fragment to back instead of staying back itself.Obstreperous
What you want to do actually ?Deathwatch
C
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.

Cilice answered 23/11, 2014 at 6:47 Comment(0)
E
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.

Elliotelliott answered 16/5, 2020 at 11:31 Comment(0)
C
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!

Clomp answered 17/11, 2016 at 15:10 Comment(0)
F
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;
    }

}
Foret answered 30/4, 2018 at 20:10 Comment(0)
A
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;
    }
}
Abscond answered 2/3, 2016 at 15:3 Comment(0)
R
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);
Revolve answered 24/9, 2017 at 23:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.