我正在尝试获取对由 java 创建的 GoogleMap 对象的引用,但我不知道如何获取此引用。
这是我的代码:
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);
这是我得到的日志:
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)
最佳答案
有几种方法可以做到这一点。
1)。如果您的目标应用程序是 API 级别 12 之后的应用程序,那么您只需使用 MapFragment
而不是 SupportMapFragment
。以下是如何将 MapFragment
添加到 Fragment
并获取对 GoogleMap
对象的引用的示例代码。
Map mapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction =
getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(mapLayout.getId(), mapFragment).commit();
然后使用 getMapAsync()
在 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.
使用 onMapReady(GoogleMap)
回调方法获取 GoogleMap 对象的句柄。本地图可供使用时会触发回调。它提供了一个非空的 GoogleMap 实例。例如,您可以使用 GoogleMap 对象设置 map 的 View 选项或添加标记。
@Override
public void onMapReady(GoogleMap map) {
map.setMyLocationEnabled(true);
}
可以引用官方文档here
2)。但是,如果您的目标应用程序早于 API 级别 12,或者出于某种原因您仍想使用 SupportMapFragment
,则还可以有两个选项。
a). 由于 map 初始化是异步的,因此您必须等待 SupportMapFragment.onCreateView()
被调用,这基本上是在 Fragment onActivityCreated 之后调用()
和 onStart()
之前。因此,如果您将 SupportMapFragment
添加到 onActivityCreated()
内的事务中,那么您将在 onStart()
中返回 getMap()
对象code> 或 onResume()
(当然,除非 Google Play 服务不可用)。下面是代码示例。
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();
}
}
}
如果您遇到任何 IllegalStateException
(Google Bug 中跟踪的问题),只需覆盖
您的 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)。您可以重写
SupportMapFragment
的onActivityCreated()
。例如。
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;
}
}
关于java - 如何获取对 Java 中创建的 GoogleMap 对象的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34966462/