片段中的空指针异常,使用 google 映射
Null pointer exception in fragment, using google maps
我在片段中获取 android google 映射时收到空指针异常。错误在 findFragmentById.I 行尝试使用
if (mMap != null) 表示地图仍然为空。我该怎么做才能解决这个问题?
在MapActivity.java,
//Relevant imports
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
enter code here
public class MapView extends Fragment {
GoogleMap mMap;
LatLng mLocation = new LatLng(1.379348, 103.849876);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.map_view, container, false);
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Zoom
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLocation, 17));
Marker mMarker = mMap.addMarker(new MarkerOptions()
.position(mLocation)
.title("School")
.snippet("NTU")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
mMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
public boolean onMarkerClick(Marker marker){
Toast.makeText(getActivity().getApplicationContext(), "Welcome to " + marker.getTitle(), Toast.LENGTH_LONG);
return false;
}
});
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener(){
@Override
public void onInfoWindowClick(Marker arg0) {
// TODO Auto-generated method stub
}
});
return rootView;
}
}
在map_view.xml,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
为了将 SupportMapFragment 嵌套在片段中,您需要使用 getChildFragmentManager()
而不是 getFragmentManager()
。
所以,你会改变这个:
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
为此,还将所有引用 mMap
的代码移动到 onResume()
:
mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
如果你走这条路,你还需要修复布局 xml 以使用 SupportMapFragment:
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
但是,如果不需要,最好不要嵌套 Fragment,因为它会导致 other problems。
更好的方法是让 Fragment 扩展 SupportMapFragment。这样做,您甚至不需要布局 xml 文件。
示例:
public class MapView extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MapView() {
}
@Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
}
}
你可以这样试试吗?
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity 或 片段:
private GoogleMap mMap;
private MapView mapView;
在 onCreate() 上:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map,container, false)
initializaMap(rootView, savedInstanceState);
return rootView;
}
在 onResume()
@Override
public void onResume() {
if(mapView!=null){
mapView.onResume();
}
super.onResume();
}
on onDestroy()
@Override
public void onDestroy() {
if(mapView!=null){
mapView.onDestroy();
}
super.onDestroy();
}
on onLowMemory()
@Override
public void onLowMemory() {
if(mapView!=null){
mapView.onLowMemory();
}
super.onLowMemory();
}
添加新方法:
private void initializaMap(View rootView, Bundle savedInstanceState){
MapsInitializer.initialize(getActivity());
switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity())) {
case ConnectionResult.SUCCESS:
mapView = (MapView) rootView.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (mapView != null) {
mMap = mapView.getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
UiSettings mUiSettings = mMap.getUiSettings();
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.zoomTo(zoomLevel));
mUiSettings.setCompassEnabled(true);
mUiSettings.setMyLocationButtonEnabled(false);
mMap.setOnMarkerClickListener(this);
}
break;
case ConnectionResult.SERVICE_MISSING:
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
break;
default:
}
}
希望对您有所帮助。
我在片段中获取 android google 映射时收到空指针异常。错误在 findFragmentById.I 行尝试使用 if (mMap != null) 表示地图仍然为空。我该怎么做才能解决这个问题?
在MapActivity.java,
//Relevant imports
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
enter code here
public class MapView extends Fragment {
GoogleMap mMap;
LatLng mLocation = new LatLng(1.379348, 103.849876);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.map_view, container, false);
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Zoom
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLocation, 17));
Marker mMarker = mMap.addMarker(new MarkerOptions()
.position(mLocation)
.title("School")
.snippet("NTU")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
mMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
public boolean onMarkerClick(Marker marker){
Toast.makeText(getActivity().getApplicationContext(), "Welcome to " + marker.getTitle(), Toast.LENGTH_LONG);
return false;
}
});
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener(){
@Override
public void onInfoWindowClick(Marker arg0) {
// TODO Auto-generated method stub
}
});
return rootView;
}
}
在map_view.xml,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
为了将 SupportMapFragment 嵌套在片段中,您需要使用 getChildFragmentManager()
而不是 getFragmentManager()
。
所以,你会改变这个:
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
为此,还将所有引用 mMap
的代码移动到 onResume()
:
mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
如果你走这条路,你还需要修复布局 xml 以使用 SupportMapFragment:
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
但是,如果不需要,最好不要嵌套 Fragment,因为它会导致 other problems。
更好的方法是让 Fragment 扩展 SupportMapFragment。这样做,您甚至不需要布局 xml 文件。
示例:
public class MapView extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MapView() {
}
@Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
}
}
你可以这样试试吗?
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity 或 片段:
private GoogleMap mMap;
private MapView mapView;
在 onCreate() 上:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map,container, false)
initializaMap(rootView, savedInstanceState);
return rootView;
}
在 onResume()
@Override
public void onResume() {
if(mapView!=null){
mapView.onResume();
}
super.onResume();
}
on onDestroy()
@Override
public void onDestroy() {
if(mapView!=null){
mapView.onDestroy();
}
super.onDestroy();
}
on onLowMemory()
@Override
public void onLowMemory() {
if(mapView!=null){
mapView.onLowMemory();
}
super.onLowMemory();
}
添加新方法:
private void initializaMap(View rootView, Bundle savedInstanceState){
MapsInitializer.initialize(getActivity());
switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity())) {
case ConnectionResult.SUCCESS:
mapView = (MapView) rootView.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (mapView != null) {
mMap = mapView.getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
UiSettings mUiSettings = mMap.getUiSettings();
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.zoomTo(zoomLevel));
mUiSettings.setCompassEnabled(true);
mUiSettings.setMyLocationButtonEnabled(false);
mMap.setOnMarkerClickListener(this);
}
break;
case ConnectionResult.SERVICE_MISSING:
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
break;
default:
}
}
希望对您有所帮助。