Reputation: 273
I'm trying to get a reference to a GoogleMap object created java, and i don't know how to get this reference.
Here's my code:
LinearLayout mapLayout = new LinearLayout(customToursActivity);
mapLayout.setId(generateViewId(rootView));
int mapLayoutHeight = Math.round(getResources().getDimension(R.dimen.custom_tour_list_map_size));
mapLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, mapLayoutHeight));
layout.addView(mapLayout);
FragmentManager fm = getChildFragmentManager();
SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(mapLayout.getId(), supportMapFragment).commit();
GoogleMap mMap = supportMapFragment.getMap();
mMap.setMyLocationEnabled(true);
Here's the log i got:
01-23 17:09:54.168 3795-3795/abff.googlemapsappteste E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: abff.googlemapsappteste, PID: 3795 java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(boolean)' on a null object reference at abff.googlemapsappteste.CustomToursList.createPlacemarksList(CustomToursList.java:458) at abff.googlemapsappteste.CustomToursList.onCreateView(CustomToursList.java:73) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501) at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490) at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) at android.support.v4.view.ViewPager.populate(ViewPager.java:1105) at android.support.v4.view.ViewPager.populate(ViewPager.java:951) at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1473) at android.view.View.measure(View.java:17637) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124) at android.view.View.measure(View.java:17637) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:444) at android.view.View.measure(View.java:17637) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.view.View.measure(View.java:17637) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17637) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2618) at android.view.View.measure(View.java:17637) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2019) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1177) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1383) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1065) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5901) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:211) at android.app.ActivityThread.main(ActivityThread.java:5389) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Upvotes: 0
Views: 1720
Reputation: 4091
There are couple of ways to do the same.
1). If you are targeting an application after API level 12, then you can simply make use of MapFragment
instead of SupportMapFragment
. Below is the sample code how you can add MapFragment
to your Fragment
and get reference to GoogleMap
Object.
Map mapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction =
getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(mapLayout.getId(), mapFragment).commit();
Then use getMapAsync()
to set the callback on the fragment.
mapFragment.getMapAsync(this); // your fragment need to implement `OnMapReadyCallback`
Note: getMapAsync() must be called from the main thread, and the callback will be executed in the main thread. If Google Play services is not installed on the user's device, the callback will not be triggered until the user installs Play services.
Use the onMapReady(GoogleMap)
callback method to get a handle to the GoogleMap object. The callback is triggered when the map is ready to be used. It provides a non-null instance of GoogleMap. You can use the GoogleMap object to set the view options for the map or add a marker, for example.
@Override
public void onMapReady(GoogleMap map) {
map.setMyLocationEnabled(true);
}
you can refer official documentation here
2). But if you are targeting an application earlier than API level 12 or you still want to use SupportMapFragment
for some reason, you can further have two otpions.
a). Since the map initialization is async, you have to wait for SupportMapFragment.onCreateView()
to be called which is basically after your Fragment onActivityCreated()
and before onStart()
. So if you add SupportMapFragment
to transaction inside onActivityCreated()
then you will have getMap()
returning object in onStart()
or onResume()
(unless of course Google Play Services is not available). Below is the code sample.
public class MyFragment extends Fragment {
private SupportMapFragment mSupportMapFragment;
private GoogleMap mGoogleMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_with_map, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
mSupportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(mapLayout.getId(),mSupportMapFragment).commit();
}
@Override
public void onResume() {
super.onResume();
if (mGoogleMap == null) {
mGoogleMap = mSupportMapFragment.getMap();
}
}
}
If you face any IllegalStateException
(an issue tracked in Google Bugs) just Override
your Fragment onDetach()
@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);
}
}
b). You can Override
the onActivityCreated()
of the SupportMapFragment
. For example.
public class MyFragment extends Fragment {
private SupportMapFragment mSupportMapFragment;
private GoogleMap mGoogleMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_with_map, container, false);
mSupportMapFragment = new SupportMapFragment() {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mGoogleMap = mSupportMapFragment.getMap();
if (mGoogleMap != null) {
mGoogleMap.setMyLocationEnabled(true);
}
}
};
getChildFragmentManager().beginTransaction().replace(mapLayout.getId(), mSupportMapFragment).commit();;
return view;
}
}
Upvotes: 1