从未在Fragment中调用MapView.onMapReady以在MapView中加载Google Map

时间:2016-04-23 09:58:47

标签: android google-maps android-mapview

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

片段按需要实现OnMapReadyCallback,在onCreateView我得到MapView并致电getMapAsync。如果我在该方法上放置断点,它将始终被击中,onMapReady内的断点从未被击中。没有例外。

我还在文件res/values/google_maps_api.xml中提供了有效的Google Maps 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();
    }
}

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

6 个答案:

答案 0 :(得分:12)

阅读MapView documentation。特别是:

  

此类的用户必须将包含此视图的ActivityFragment的所有生命周期方法转发到此类中的相应方法。特别是,您必须转发以下方法:

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

答案 1 :(得分:4)

地图片段是您向另一个片段膨胀的布局的一部分(让我们称之为父片段)。膨胀的片段成为父片段的活动BUT的子片段。您必须询问父片段的子片段管理器:

注意:只需扩展简单片段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;
}`

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

来自@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

答案 4 :(得分:0)

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

  

完全交互模式中使用API​​时,MapView类的用户必须将所有活动生命周期方法转发到MapView类中的相应方法。生命周期方法的示例包括onCreate()onDestroy()onResume()onPause()

     

精简模式中使用MapView类时,转发生命周期事件是可选的,但以下情况除外:

     
      
  • 必须致电onCreate(),否则不会显示地图。

  •   
  • 如果您希望在精简模式地图上显示“我的位置”点并使用默认位置来源,则需要拨打onResume()onPause(),因为位置来源只会在这些电话之间更新。如果您使用自己的位置来源,则无需调用这两种方法。

  •   

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

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

答案 5 :(得分:0)

首先让您知道这一点。我正在将Google Map片段用作另一个片段内的子片段,其中GoogleMapFragment扩展了 com.google.android.gms.maps.SupportMapFragment

我在onCreateView的GoogleMapFragment中使用了这段代码,也可以在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);
       }
 });

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