Google Maps Fragment在片段内返回null

axt*_*scz 18 android google-maps android-fragments

所以我有一个包含地图片段的空片段.每当我尝试激活包含地图的片段时,我的应用程序崩溃并在此行返回空指针错误:

map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
                .getMap();
Run Code Online (Sandbox Code Playgroud)

完整错误消息:

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)
Run Code Online (Sandbox Code Playgroud)

这是我的片段代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的父片段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>
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么地图片段返回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);
Run Code Online (Sandbox Code Playgroud)

它仍然返回一个空指针值

Cab*_*zas 26

我已经解决了这个问题.当我有一个viewpager时,这一行:

mMap = ((SupportMapFragment) MainActivity.fragmentManager
                .findFragmentById(R.id.mapView)).getMap();
Run Code Online (Sandbox Code Playgroud)

你必须改变这个:

  mMap = ((SupportMapFragment) getChildFragmentManager()
            .findFragmentById(R.id.mapView)).getMap();
Run Code Online (Sandbox Code Playgroud)

  • 生命保护!:d (2认同)
  • 你结束了8个小时的痛苦我的朋友:) (2认同)

Víc*_*tos 21

您的类扩展自Fragment,并且您Fragment在布局中使用声明,但嵌套片段仅在动态添加时才起作用.

所以,你有两个选择:

1)延伸FragmentAcivity而不是Fragment应用适当的方法.

2)Fragment动态添加,如下:

// ReturnVisitDetails

MapFragment mapFragment = new MapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.rl_map_container, mapFragment).commit();
Run Code Online (Sandbox Code Playgroud)

//布局

<FrameLayout
        android:id="@+id/rl_map_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)

- 更新 -

在以下位置使用Google地图的完整示例Fragment:

// 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);
    }

}
Run Code Online (Sandbox Code Playgroud)

// 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;
    }

}
Run Code Online (Sandbox Code Playgroud)

// 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);
    }

}
Run Code Online (Sandbox Code Playgroud)

//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>
Run Code Online (Sandbox Code Playgroud)

//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>
Run Code Online (Sandbox Code Playgroud)


kal*_*lan 10

当我尝试将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
Run Code Online (Sandbox Code Playgroud)

我将它与片段活动一起使用,如下所示:

((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapToday)).getMap();
Run Code Online (Sandbox Code Playgroud)

但问题是,早些时候我使用的是特定版本的Google Play服务(4.3.23).

但Gradle构建选择最新版本(compile 'com.google.android.gms:play-services:+')

我尝试了一些其他特定版本,如(6.1.71).但仍然给出零点异常.

我使用了与以前相同的旧版本并且它有效.

compile 'com.google.android.gms:play-services:4.3.23'
Run Code Online (Sandbox Code Playgroud)

这对我来说是一个临时解决方案.但是,当我需要更新到新的播放服务库时,这将是一个问题.

当我尝试这样的时候,似乎没有特定的地图库,这个版本可用于Gradle构建:

compile 'com.google.android.gms:play-services-maps:4.3.23'
Run Code Online (Sandbox Code Playgroud)


Mri*_*ank 9

我在这方面搜索了很多主题,因为我在使用较旧的Google Play服务时遇到了同样的问题.正如维克托所说,你的类从片段延伸,它必须使用布局中定义的另一个片段,所以最好的方法是使用getChildFragmentManager()而不是getSupportFragmentManager().

另外getMap() method is deprecated,现在在谷歌文档中提到.有关详情,请参阅此处: - https://developers.google.com/android/reference/com/google/android/gms/maps/MapFragment.html#getMap()

下面是我在旧游戏服务的各种设备上测试的工作代码.如果设备具有较旧的Google Play服务,并且如果GoogleMap返回null的对象为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;
    }

}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此主题.


Rhi*_*art 7

这可能是迁移到21的目标sdk版本的问题吗?如果是这样,您可能会对以下解决方案感兴趣:

MapFragment或MapView getMap()在Lollipop上返回null