我已经实现了一个在运行时添加MapFragment
的活动。 MapFragment
xml有静态fragment
,我试图在运行时添加。我还发现Lollipop在运行时添加了地图片段存在一些问题。请检查Issue raised和temporary solution
我也在下面给出了我的代码,
fragment_map.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=".fragment.MapsFragment">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="appCreators.bloodfinder.activity.MapsActivity"/>
<include
android:id="@+id/layout"
layout="@layout/template_custom_spinner"/>
</FrameLayout>
MapsFragment.java
实施onMapReadyCallback
public class MapsFragment extends SupportMapFragment implements OnMapReadyCallback
在onResume
回调
@Override
public void onResume() {
super.onResume();
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
}
这总是让我归零,我也试过了,
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
这也会返回NullPointerException
MapsActivity.java
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
我在活动回调的onCreate
方法中添加了这个。
我无法弄清楚为什么我仍然会NullPointerException
!
有时候我会Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
帮助将不胜感激!
更新:仍然没有修复我收到以下错误。我查看了日志,但不知道为什么会发生这种情况。
Unable to resume activity {MapsActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
答案 0 :(得分:11)
我终于通过观察SO中给出的答案为自己解决了这个问题。我比较了代码和答案中的代码。在我看来,这个API存在一些混淆,谷歌的实施非常广泛。我反复抛出这个异常:
Attempt to invoke interface method 'void com.google.maps.api.android.lib6.e.fl.o()' on a null object reference
我仍然不知道在SO问题中这些实现中的某些实现是否有相同的异常,但这对我有用,并且可能适用于其他人。
这些是您需要检查的内容:
确保您拥有这两个(我只有api密钥元数据)
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
你有一个像这样的xml片段,其中class属性正确如下
<fragment
android:id="@+id/google_map_fragment"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
在我的情况下,地图片段是一个孩子,在另一个片段中。
这个父片段显然不应该是MapFragment或SupportMapFragment。将它从SupportMapFragment更改为Fragment后,地图显示完全正常。
public class ParentFragment extends Fragment {
我之前保留了以前的所有内容,但是没有在onCreateView中获取地图,而是在onViewCreated中得到了这样的内容:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.rewards_google_map_area);
if (mapFragment != null) {
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null && mapFragment.getMap() != null) {
googleMap=mapFragment.getMap();
//after this you do whatever you want with the map
}
}
}
我没有改变任何其他东西,我没有弄乱rootView或parentView。正如你在@Konstantin Loginov的回答中看到的那样
尝试一下,让我知道。
答案 1 :(得分:2)
前一段时间我一直在努力解决类似的问题。
关键是在getMap()
onViewCreated()
Fragment
的适当时刻public class LocationFragment extends Fragment {
private SupportMapFragment locationMap;
private View rootView;
protected View getFragmentView() {
View view = getView();
if (view == null) {
view = rootView;
}
return view;
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = getFragmentView();
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
}
}
try {
rootView = inflater.inflate(R.layout.fragment_signup_specify_location, container, false);
} catch (InflateException ex) {
Log.e(LOG_TAG, "Inflate Exception in onCreateView; Caused by map fragment", ex);
}
......
return getFragmentView();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
locationMap = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.locationMap);
if (locationMap != null) {
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null && locationMap.getMap() != null) {
locationMap.getMap().setMyLocationEnabled(true);
}
}
}
}
:{/ 1}
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/locationMap"
android:layout_above="@+id/locationLabelTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
它的XML看起来像你的:
onViewCreated()
然后,在Activity
中,您可以通知hide.bs.modal
您的地图片段已准备好使用。
我希望,这有帮助
答案 2 :(得分:1)
在我的情况下,我在Fragment的xml中静态使用原始MapView
。问题是我必须将呼叫转移mMapView.onCreate(...)
移至onViewCreated(...)
,因为onCreate()
mMapView
尚未充气。如果您不使用MapView
,则应仔细检查您拨打getMap()
的时刻。我必须在内部MapView被夸大之后。
答案 3 :(得分:1)
如果使用mapView,只需确保在mapView.onCreate()
之前调用了mapView.getMapAsync()
。如果您使用片段并且视图仍未初始化,则还可以使用mapView.onCreate()
方法调用onViewCreated()
。
答案 4 :(得分:0)
UPDATE 2019
如果您仍然遇到此问题,请尝试以下方法:
请勿扩展SupportMapFrangemt!
public class MyFragment extends Fragment {
private SupportMapFragment fragment;
private GoogleMap map;
@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();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
}
}
}