blackHawk
blackHawk

Reputation: 6307

GoogleMap Fragment returning null object

I want to have a separate class from MainActivity for initializing map and have static method for initializing so it remains same across project and any class can use this googlemap object returning from class, I wrote a separate class

public class MapFragment extends AppCompatActivity{

public static SupportMapFragment mapFrag;

public static SupportMapFragment GetMapObj() {
   mapFrag = (SupportMapFragment) new MainActivity().
   getSupportFragmentManager().findFragmentById(R.id.frag_map);
}

And in MainActivity using it like this

SupportMapFragment mapFragment = MapFragment.GetMapObj();
        mapFragment.getMapAsync(this);

I have 2 xml 1 for the class above and 1 for mainActivity I dnt know where should I put my

 <fragment
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/frag_map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    tools:context="com.example.sarahn.clientapimap.MainActivity"
    />

And having said all this my application crashing on null pointer exception that attempt to invoke getAsncMap on null object reference

}

Upvotes: 0

Views: 169

Answers (4)

Pablo Baxter
Pablo Baxter

Reputation: 2234

The issue is that you are trying to create an new context rather than having the OS do it. You have to use startActivity on an existing context to create a new activity.

As for how you want to get your map object, here is an example:

public class MapFragment extends AppCompatActivity{

    public static SupportMapFragment mapFrag;

    public static SupportMapFragment GetMapObj(FragmentActivity activity) {
       mapFrag = (SupportMapFragment) activity.
         getSupportFragmentManager().findFragmentById(R.id.frag_map);
    }
}

And in your activity, just call this:

SupportMapFragment mapFragment = MapFragment.GetMapObj(this);
        mapFragment.getMapAsync(this);

Upvotes: 0

Kevin Krumwiede
Kevin Krumwiede

Reputation: 10298

You can extend SupportMapFragment and initialize the map in the fragment's own onCreate method. This avoids cluttering your activity with code that logically belongs to the fragment.

public class MyMapFragment extends SupportMapFragment {
    @Override
    public void onCreate(final Bundle bundle) {
        super.onCreate(bundle);
        getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(final GoogleMap map) {
                // configure the map here
            }
        });
    }
}

Then put it in your activity XML just like you would an ordinary SupportMapFragment.

<fragment
    android:id="@+id/map"
    android:name="com.myapp.MyMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

If you still need to access the fragment from your activity, you'd call getSupportFragmentManager().findFragmentById(R.id.map). But since the fragment configures the map, the activity may no longer need to access it. An activity that uses fragments is often little more than onCreate calling setContentView.

Upvotes: 1

jmarkstar
jmarkstar

Reputation: 1335

Try this if you want your activity do something when the user does something in the map.

public class YourFragment extends Fragment implements OnMapReadyCallback,
    GoogleMap.OnMapClickListener,
    GoogleMap.OnMarkerClickListener{

    private MapFragment mapFragment;
    private GoogleMap mMap;
    private OnMapListener onMapListener;

    public static YourFragment newInstance(){
        return new YourFragment();
    }

    @Override public void onAttach(Context context) {
        super.onAttach(context);
        try {
            this.onMapListener = (OnMapListener)context;
        }
        catch (final ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement OnMapListener");
        }
    }

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

        mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id. frag_map); 
        mapFragment.getMapAsync(this); //Its async, It could last a little bit and 
        //that is the reason why you are getting NULL,
        // to work Asynchronously you should implement the Callback 'OnMapReadyCallback'.

        return rootView;
    }

    @Override public void onMapReady(GoogleMap googleMap) { 
        mMap = googleMap; 
        mMap.setOnMapClickListener(this);
        mMap.setOnMarkerClickListener(this);
    }

    @Override public void onMapClick(LatLng latLng) {
        onMapListener.onMapClick(latLng);
    }

    @Override public boolean onMarkerClick(Marker marker) {
        onMapListener.onMarkerClick(marker);
    }

    public interface OnMapListener{
        void onMapClick(LatLng latLng);
        void onMarkerClick(Marker marker);
    }
}


public class YourActivity extends AppCompatActivity implements OnMapListener {

    @Override protected void onCreate(Bundle savedInstanceState) {

        ...
        YourFragment newFragment = YourFragment.newInstance();
        ...
    }

    public void onMapClick(LatLng latLng){
    //do something on your activity
    }
    public void onMarkerClick(Marker marker){
    //do something on your activity
    }          
}

Upvotes: 1

rafsanahmad007
rafsanahmad007

Reputation: 23881

You are getting NullPointerException as your mapFragment is not initialized properly.

Initialize the SupportMapFragment in your MainActivity instead.

in main_activity_xml:

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

Now in your MainActivity

 public class MainActivity extends FragmentActivity implements OnMapReadyCallback{


  SupportMapFragment smp;
  GoogleMap mMap;

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity_xml);
        smp = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        smp.getMapAsync(this);
        }

    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;
        //map initialized
    }
}

Upvotes: 1

Related Questions