MapView.onMapReady 从未在 Fragment 中调用加载 Google MapView 中的地图

MapView.onMapReady never called in Fragment for load Google Map in MapView

我将尝试在名为 RoeteFragment 的片段上的 Android 应用程序中显示地图。如果我调试我的代码,我会发现方法 onMapReady 从未被调用,因此地图不会加载。

该片段根据需要实现 OnMapReadyCallback,在 onCreateView 中我得到 MapView 并调用 getMapAsync。如果我在该方法上放置断点,它将始终被命中,onMapReady 内的断点从未被命中。没有抛出异常。

我在文件 res/values/google_maps_api.xml.

中还有一个有效的 Google 地图 API 密钥

这是我的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.gms.maps.MapView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map" />

</RelativeLayout>
public class RoeteFragment extends Fragment implements OnMapReadyCallback {

    private MapView mapView;
    private static Roete _roete;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_roete, container, false);
        mapView = (MapView) view.findViewById(R.id.map);
        mapView.getMapAsync(this);
        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        if (_roete != null && _roete.getAankomstLocatie() != null && _roete.getVertrekLocatie() != null) {
            LatLng aankomst = new LatLng(_roete.getAankomstLocatie().getLatitude(), _roete.getAankomstLocatie().getLongitude());
            googleMap.addMarker(new MarkerOptions().position(aankomst).title("aankomst"));
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(aankomst));

            LatLng vertrek = new LatLng(_roete.getVertrekLocatie().getLatitude(), _roete.getVertrekLocatie().getLongitude());
            googleMap.addMarker(new MarkerOptions().position(vertrek).title("vertrek"));
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(vertrek));
        }
    }

    public static Fragment newInstance() {
        return new RoeteFragment ();
    }

    public static Fragment newInstance(Roete roete) {
        _roete = roete;
        return newInstance();
    }
}

你能在我的代码中提交错误吗?

根据@androidnoobdev 的评论,他说要使用 SupportMapFragment,我已将布局文件中的代码更新为:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

     <fragment
        class="com.google.android.gms.maps.SupportMapFragment"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>

</RelativeLayout>

更新 删除支持片段后不需要的 MapView b'z。

感谢@androidnoobdev

尝试使用支持地图片段。它也将在片段中工作。 https://developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment#developer-guide

对于相机和缩放级别,请检查此 -https://developers.google.com/maps/documentation/android-api/views#introduction

试试这个,如果有帮助,请接受它作为答案。

阅读MapView documentation。特别是:

Users of this class must forward all the life cycle methods from the Activity or Fragment containing this view to the corresponding ones in this class. In particular, you must forward on the following methods:

  • onCreate(Bundle)
  • onResume()
  • onPause()
  • onDestroy()
  • onSaveInstanceState()
  • onLowMemory()

您应该从 doc 中注意到这一点:

When using the API in fully interactive mode, users of the MapView class must forward all the activity life cycle methods to the corresponding methods in the MapView class. Examples of the life cycle methods include onCreate(), onDestroy(), onResume(), and onPause().

When using the MapView class in lite mode, forwarding lifecycle events is optional, except for the following situations:

  • It is mandatory to call onCreate(), otherwise no map will appear.

  • If you wish to show the My Location dot on your lite mode map and use the default location source, you will need to call onResume() and onPause(), because the location source will only update between these calls. If you use your own location source, it's not necessary to call these two methods.

因此,您在 onCreateView 中缺少 mapView.onCreate(mapViewBundle),并且由于您的地图处于 完全交互模式 ,您必须照顾整个生命周期,像这样:

public class RoeteFragment extends Fragment implements OnMapReadyCallback {

    private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";

    private MapView mapView;
    private static Roete _roete;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_roete, container, false);
        mapView = (MapView) view.findViewById(R.id.map);

        // *** IMPORTANT ***
        // MapView requires that the Bundle you pass contain ONLY MapView SDK
        // objects or sub-Bundles.
        Bundle mapViewBundle = null;
        if (savedInstanceState != null) {
            mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
        }
        mapView.onCreate(mapViewBundle);
        mapView.getMapAsync(this);
        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        if (_roete != null && _roete.getAankomstLocatie() != null && _roete.getVertrekLocatie() != null) {
            LatLng aankomst = new LatLng(_roete.getAankomstLocatie().getLatitude(), _roete.getAankomstLocatie().getLongitude());
            googleMap.addMarker(new MarkerOptions().position(aankomst).title("aankomst"));
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(aankomst));

            LatLng vertrek = new LatLng(_roete.getVertrekLocatie().getLatitude(), _roete.getVertrekLocatie().getLongitude());
            googleMap.addMarker(new MarkerOptions().position(vertrek).title("vertrek"));
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(vertrek));
        }
    }

    public static Fragment newInstance() {
        return new RoeteFragment ();
    }

    public static Fragment newInstance(Roete roete) {
        _roete = roete;
        return newInstance();
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
        if (mapViewBundle == null) {
            mapViewBundle = new Bundle();
            outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
        }

        mapView.onSaveInstanceState(mapViewBundle);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }
}

地图片段是您扩展到另一个片段(我们称之为父片段)的布局的一部分。膨胀的片段成为父片段的 activity 但不是 activity 的子片段。你得问父片段的子片段管理器:

注意:只需扩展简单片段public class MapsFragments extends Fragment implements OnMapReadyCallback {} XML 文件

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.elektrasoft.Test.MapsFragments" />

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    Log.d("check","onCreateView");
    // Inflate the layout for this fragment
    View view= inflater.inflate(R.layout.fragment_maps_fragments, container, false);
    // Gets the MapView from the XML layout and creates it
    final SupportMapFragment myMAPF = (SupportMapFragment) getChildFragmentManager()
            .findFragmentById(R.id.map);
    myMAPF.getMapAsync(this);
    return  view;
}`

先让你知道这个。我正在使用 Google Map 片段作为另一个片段中的子片段,其中 GoogleMapFragment 范围为 com.google.android.gms.maps.SupportMapFragment

我在GoogleMapFragment中的onCreateView中使用了这段代码,你也可以在onStart中使用。 onMapReady 未调用时

MapFragment mapFragment = new MapFragment();
mapFragment.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(GoogleMap map) {
           mCallback.onMapReady(map);
      }
});

我刚刚删除了这个

MapFragment mapFragment = new MapFragment();

然后开始这样打电话

this.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(GoogleMap map) {
           Log.i(TAG, "onMapReady: onCreateView");
           mCallback.onMapReady(map);
       }
 });

我希望这可能对某人有所帮助。