Google地图片段在片段内返回空值
所以我有一个包含地图片段的空片段。 每当我尝试激活包含地图的片段,我的应用程序崩溃,并在这一行返回一个空指针错误:
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) .getMap();
完整的错误信息:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.GoogleMap com.google.android.gms.maps.MapFragment.getMap()' on a null object reference at com.collusion.serviceassistant.ReturnVisitDetails.onViewCreated(ReturnVisitDetails.java:39) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:904) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) at android.app.BackStackRecord.run(BackStackRecord.java:684) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5001) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
这是我的片段代码:
import android.app.Activity; import android.app.Dialog; import android.net.Uri; import android.os.Bundle; import android.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; public class ReturnVisitDetails extends Fragment { static final LatLng HAMBURG = new LatLng(53.558, 9.927); static final LatLng KIEL = new LatLng(53.551, 9.993); private GoogleMap map; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_return_visit_add, container, false); return rootView; } public void onViewCreated(View view, Bundle savedInstanceState) { // Get a handle to the Map Fragment map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) .getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); } }
和我的父级片段XML布局:
<RelativeLayout 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="com.collusion.serviceassistant.ReturnVisitDetails" android:background="#009688"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> </RelativeLayout>
任何人都有一个想法,为什么地图片段返回null?
编辑:所以现在我有这个代码来初始化地图:
MapFragment mapFragment = new MapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.rl_map_container, mapFragment).commit(); map = mapFragment.getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
它仍然返回一个空指针值
当我尝试将我的Eclipse项目移植到Android Studio项目时,发生了这个问题。
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.GoogleMap com.google.android.gms.maps.SupportMapFragment.getMap()' on a null object reference
我用这样的片段活动:
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapToday)).getMap();
不过,问题在于,之前我使用的是特定版本的Google Play服务(4.3.23)。
但是Gradle构buildselect了最新的版本( compile 'com.google.android.gms:play-services:+')
我尝试了一些其他特定的版本,如(6.1.71)。 但是还是给了零点例外。
我使用了和以前一样的旧版本,并且工作。
compile 'com.google.android.gms:play-services:4.3.23'
这对我来说是一个临时的解决scheme。 但是,当我需要更新到新的播放服务库时,这将是一个问题。
似乎没有具体的地图库,这个版本可用于Gradle构build,当我尝试这样的:
compile 'com.google.android.gms:play-services-maps:4.3.23'
我已经解决了这个问题。 这一行当我有一个viewpager:
mMap = ((SupportMapFragment) MainActivity.fragmentManager .findFragmentById(R.id.mapView)).getMap();
你必须改变这个:
mMap = ((SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.mapView)).getMap();
您的类从Fragment
扩展而来,并且您正在使用在布局中声明的Fragment
,但嵌套片段仅在dynamic添加时才起作用。
所以,你有两个select:
1)从FragmentAcivity
扩展而不是Fragment
并采用适当的方法。
2)dynamic添加Fragment
,如下所示:
// ReturnVisitDetails
MapFragment mapFragment = new MapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.rl_map_container, mapFragment).commit();
//布局
<FrameLayout android:id="@+id/rl_map_container" android:layout_width="match_parent" android:layout_height="match_parent" />
– 更新 –
在Fragment
使用Google地图的完整示例:
// TestFragmentActivity
public class TestFragmentActivity extends android.support.v4.app.FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_fragment_activity); } }
// TestFragment
public class TestFragment extends android.support.v4.app.Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.test_fragment, container, false); CustomMapFragment mapFragment = new CustomMapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.map_container, mapFragment).commit(); return rootView; } }
// CustomMapFragment
public class CustomMapFragment extends com.google.android.gms.maps.SupportMapFragment { private final LatLng HAMBURG = new LatLng(53.558, 9.927); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); GoogleMap googleMap = getMap(); googleMap.addMarker(new MarkerOptions().position(HAMBURG).title("Hamburg")); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); googleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); } }
//test_fragment_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/map" class="your_package.TestFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
//test_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/map_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
我search了很多的线程,因为我在旧的谷歌播放服务有同样的问题。 正如维克多说,你的类从片段扩展,它必须使用布局中定义的另一个片段,所以最好的办法是使用getChildFragmentManager()
而不是getSupportFragmentManager()
。
另外getMap() method is deprecated
现在已经getMap() method is deprecated
了,正如google文档中提到的那样。 请参阅以下内容: – https://developers.google.com/android/reference/com/google/android/gms/maps/MapFragment.html#getMap();
以下是我在老玩法服务的各种设备上testing的工作代码。 如果设备有较旧的Google Play服务,并且GoogleMap
对象返回null,则会生成默认消息:
class MyFragment extends Fragment { SupportMapFragment myMapFragment; GoogleMap myMap; View convertView; FragmentManager fm; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { convertView=inflater.inflate(R.layout.mymap,null); fm=getChildFragmentManager(); myMapFragment=(SupportMapFragment) fm.findFragmentById(R.id.myMapId); // here instead of using getMap(), we are using getMapAsync() which returns a callback and shows map only when it gets ready. //it automatically checks for null pointer or older play services version, getMap() is deprecated as mentioned in google docs. myMapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googlemap) { // TODO Auto-generated method stub myMap=googlemap; startMap(); } }); return convertView; } }
看到这个线程的更多信息。
这可能是一个迁移到21的目标sdk版本的问题? 如果是这样,下面的解决scheme可能是你感兴趣的:
MapFragment或MapView getMap()在棒棒糖上返回null
尝试使用SupportMapFragment而不是MapFragment。 这段代码适用于我的片段,只是试过了:
import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; public class MapFragment extends Fragment { private GoogleMap map; static final LatLng HAMBURG = new LatLng(53.558, 9.927); static final LatLng KIEL = new LatLng(53.551, 9.993); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_map, container, false); // Get a handle to the Map Fragment map = ((SupportMapFragment) getFragmentManager().findFragmentById( R.id.map)).getMap(); Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG) .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions() .position(KIEL) .title("Kiel") .snippet("Kiel is cool") .icon(BitmapDescriptorFactory .fromResource(R.drawable.ic_launcher))); // Move the camera instantly to hamburg with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); return rootView; } }
和你的布局:
<RelativeLayout 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=".MainActivity" > <fragment android:id="@+id/map" android:name="com.example.test.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> </RelativeLayout>
问题可能与您的targetSdkVersion
高于Android支持库使用的版本有关。
那是我的情况,在我们一直在研究targetSdkVersion
的项目targetSdkVersion
是21,而Support Library版本是19.0.0。 改变targetSdkVersion
为19固定的问题。
我可以面对同样的问题,但最终我可以解决这个错误。现在地图正确地显示…
=>在onCreateView()方法内的Fragment中调用initilizeMap()方法…
=>声明全局variables像,
private GoogleMap googleMap; private void initilizeMap() { try { // Changing marker icon // marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_marker_icon))); // adding marker if (googleMap == null) { googleMap = ((MapFragment)getActivity().getFragmentManager() .findFragmentById(R.id.map)).getMap(); // create marker MarkerOptions marker = new MarkerOptions().position( new LatLng(latitude, longitude)).title( "YourCare"); // Changing marker icon MarkerOptions icon = marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_ROSE)); // adding marker LatLng latLng = new LatLng(latitude, longitude); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( latLng, 15); googleMap.animateCamera(cameraUpdate); // locationManager.removeUpdates(this); googleMap.addMarker(marker); googleMap.setMyLocationEnabled(true); // check if map is created successfully or not if (googleMap == null) { Toast.makeText(getActivity(), "Sorry! unable to create maps", Toast.LENGTH_SHORT) .show(); } } } catch (Exception e) { System.out.print("Error :" + e.getMessage()); } }