Error trying to load map in a fragment

1

I'm having a problem loading Maps, I'm using SupportMapFragment, it does not show any visible error in the code but in Logcat it shows me the following error:

  

java.lang.NullPointerException: Attempt to invoke virtual method 'void   com.google.android.gms.maps.SupportMapFragment.getMapAsync (com.google.android.gms.maps.OnMapReadyCallback) '   on a null object reference                                                                                  at   com.tecnologias.uniagustapp.fragmentos.Fragment_Rutas.onViewCreated (Fragment_Rutas.java:43)

The error is generated from here:

SupportMapFragment mapFragment = (SupportMapFragment) 
       getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

The Fragment code is as follows:

public class Fragment_Rutas extends Fragment implements OnMapReadyCallback {

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

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

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    //SupportMapFragment mapFragment2 = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    //mapFragment2.getMapAsync((OnMapReadyCallback) getActivity());

    //MapFragment fragment = (MapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    //fragment.getMapAsync(this);
}

@Override//acercamiento
public void onMapReady(GoogleMap googleMap) {
    LatLng bogota = new LatLng(4.653421, -74.145150);
    googleMap.addMarker(new MarkerOptions().position(bogota)
            .title("Uniagustiniana"));
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(bogota, 16.1f));
}
}

Next I show the XML file where I have the MapFragment tag:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tecnologias.uniagustapp.fragmentos.Fragment_Rutas"
android:orientation="vertical">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:background="#94dea7">

    <fragment
        android:id="@+id/map"
        class="com.google.android.gms.maps.MapFragment"
        android:layout_width="wrap_content"
        android:layout_height="300dp"></fragment>
</LinearLayout>

The complete code is here:

Fragment_Rutas

Thank you very much for the help.

    
asked by Ivan Alfredo 01.11.2017 в 23:16
source

2 answers

1

The problem as you comment, is generated at this point:

SupportMapFragment mapFragment = (SupportMapFragment) 
       getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

You can not call the getMapAsync() method, because it generates an error:

  

NullPointerException: Attempt to invoke virtual method 'void   com.google.android.gms.maps.SupportMapFragment.getMapAsync (

Since you are not really getting the map view reference. To avoid this problem I suggest you inflate the view within onCreateView() and there get the Map reference, to later call mapFragment.getMapAsync(this); :

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

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

    View rootView =  inflater.inflate(R.layout.fragment_rutas, container, false);

    //Si usas getActivity estas suponiendo que la vista se buscara en el layout cargado por la Activity.
    //SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map);

    SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);

    mapFragment.getMapAsync(this);

    return rootView;    

}

within fragment_rutas.xml you must have the framgment with the id map:

<fragment
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.SupportMapFragment" />
    
answered by 02.11.2017 / 00:31
source
1

When creating a fragment from another fragment you should look for it with the method getChildFragmentManager () as follows:

SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);

I add something important: If you declare the initialization of a fragment from an xml layout, it will always be generated with the same id which generates inconsistencies in the automatic reaction of android, for example, when you replace the main fragment with another one and then make a backstack pop. To solve this issue you have to remove the fragment at the moment of destroying the view so that its recreation does not generate an exception for repeated fragment ids;)

@Override
public void onDestroyView() {
    Fragment f = getChildFragmentManager().findFragmentById(R.id.map);
    if (f!=null)
        getChildFragmentManager().beginTransaction()
                .remove(f).commitAllowingStateLoss();
    super.onDestroyView();
}
    
answered by 02.11.2017 в 06:33