onMapReady is not called in the fragment
Asked Answered
W

2

6

I am building an application which is related to google maps. In this i am trying to implement the map in fragment. I am manipulating the map in OnMapReady method. But app is not calling the OnMapReady method. I implemented the same thing in activity and its working perfect. But its not working in fragment. I don't know if its the problem with fragment life cycle and i am missing something. Here is the code.

Maps_Fragment.java

    package com.example.mudasir.login;


import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
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.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class Maps_Fragment extends Fragment implements OnMapReadyCallback {

    public GoogleMap mMap;
    String[] showroom_addresses = new String[5];
    List<Address> addressList = null;
    LatLng latlng;
    LatLngBounds.Builder builder  = new LatLngBounds.Builder();
    View view1;

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

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_maps_, container, false);
    }
    @Override
    public void onViewCreated(View view,Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.maps);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {

        showroom_addresses[0] = "Dubai";
        showroom_addresses[1] = "Fujairah";
        showroom_addresses[2] = "Al Ain";
        showroom_addresses[3] = "Sharjah";
        showroom_addresses[4] = "Ras Al Khaimah";
        Geocoder geocoder = new Geocoder(getActivity());
        for(int i =0; i<5; i++) {
            try {
                addressList = geocoder.getFromLocationName(showroom_addresses[i], 1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            android.location.Address address = addressList.get(0);
            latlng = new LatLng(address.getLatitude(), address.getLongitude());
            Marker marker = googleMap.addMarker(new MarkerOptions().position(latlng).title(showroom_addresses[i]));
            builder.include(marker.getPosition());
        }

        LatLngBounds bounds = builder.build();
        int padding = 0;
        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds,padding);
        //CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new MarkerOptions().position(latlng).title(showroom_addresses[3]).getPosition(),7F);
        googleMap.animateCamera(cu);
    }

}

Maps_Fragment.xml

<FrameLayout 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.example.mudasir.login.Maps_Fragment">

    <!-- TODO: Update blank fragment layout -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout">


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

Same approach and requirement is working fine in case of activity but its something wrong in case of fragment. Please Help.

Winterfeed answered 16/9, 2016 at 20:28 Comment(0)
A
6

You must extend from

SupportMapFragment

instead of

Fragment

[EDITED]

My recommendation is to have 2 fragments: One when you don't have any result and another with the SupportFragmentManager.

In addition, in your Maps_Fragment that should extends from SupportFragmentManager, you must remove the override of onCreateView and onViewCreated, otherwise you should manage all the SupportMapFragment and I think you don't want to.

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

To implement OnMapReadyCallback, I will do it in the onActivityCreated method:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    getMapAsync(this);
}
Ansate answered 16/9, 2016 at 20:38 Comment(1)
Now the code is working but its giving the nulll exception on mapFragment.getMapAsync(this); and application is crashing.Winterfeed
S
3

A better way to implement this would be to use MapView instead of MapFragment. And do something like below

<FrameLayout 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.example.mudasir.login.Maps_Fragment">

    <!-- TODO: Update blank fragment layout -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout">

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

</FrameLayout>

And your Maps_Fragment.java class

public class Maps_Fragment extends Fragment implements OnMapReadyCallback {

    private View view;
    private MapView mapView;
    String[] showroom_addresses = new String[5];
    List<Address> addressList = null;
    LatLng latlng;
    LatLngBounds.Builder builder  = new LatLngBounds.Builder();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_maps_, container, false);

        // Gets the MapView from the XML layout and creates it
        mapView = (MapView) view.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);

        // Set the map ready callback to receive the GoogleMap object
        mapView.getMapAsync(this);           

        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        // Need to call MapsInitializer before doing any CameraUpdateFactory calls
        try {
            MapsInitializer.initialize(this.getActivity());
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace();
        }

        mGoogleMap = googleMap;

        showroom_addresses[0] = "Dubai";
        showroom_addresses[1] = "Fujairah";
        showroom_addresses[2] = "Al Ain";
        showroom_addresses[3] = "Sharjah";
        showroom_addresses[4] = "Ras Al Khaimah";
        Geocoder geocoder = new Geocoder(getActivity());
        for(int i =0; i<5; i++) {
            try {
                addressList = geocoder.getFromLocationName(showroom_addresses[i], 1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            android.location.Address address = addressList.get(0);
            latlng = new LatLng(address.getLatitude(), address.getLongitude());
            Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(latlng).title(showroom_addresses[i]));
            builder.include(marker.getPosition());
        }

        LatLngBounds bounds = builder.build();
        int padding = 0;
        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds,padding);
        //CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new MarkerOptions().position(latlng).title(showroom_addresses[3]).getPosition(),7F);
        mGoogleMap.animateCamera(cu);
    }

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

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

And please make sure you have the following imports for Fragment and Map

import android.support.v4.app.Fragment;

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.OnMapReadyCallback;
Swindle answered 16/9, 2016 at 21:12 Comment(7)
App is still crashing. java.lang.NullPointerException: Attempt to invoke interface method 'void maps.ad.z.o()' on a null object referenceWinterfeed
java.lang.NullPointerException: Attempt to invoke interface method 'void maps.ad.z.o()' on a null object referenceWinterfeed
Still Crashing.Winterfeed
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapView.onCreate(android.os.Bundle)' on a null object referenceWinterfeed
comment this line and try mapView.onCreate(null);Swindle
Let us continue this discussion in chat.Swindle
this worked perfectly for me and that could be the accepted answer!Ocreate

© 2022 - 2024 — McMap. All rights reserved.