【问题标题】:MapView.onMapReady never called in Fragment for load Google Map in MapViewMapView.onMapReady 从未在 Fragment 中调用以在 MapView 中加载 Google 地图
【发布时间】:2016-04-23 09:58:46
【问题描述】:

我将尝试在我的 Android 应用程序中在名为 RoeteFragment 的片段上显示地图。如果我调试我的代码,我会看到方法 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();
    }
}

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

【问题讨论】:

  • 尝试使用支持地图片段。它也可以在片段中工作。 developers.google.com/android/reference/com/google/android/gms/…
  • @androidnoobdev: 非常感谢它现在正在工作:)
  • @androidnoobdev:我看到的唯一一个问题是我无法使用地图。我的意思是我无法缩放或移动相机。
  • 不,你可以。地图准备好后,您可以通过缩放和所有相机对象。见文档
  • @androidnoobdev: 对不起,我对地图无能为力。

标签: android google-maps android-mapview


【解决方案1】:

阅读MapView documentation。特别是:

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

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

【讨论】:

  • 这应该是正确的答案,因为它仍然基于 MapView。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 感谢您更新我的答案,这确实是正确的代码! :) 这个答案对我没有帮助......
    • 感谢您的帮助,我赞成您的回答。
    • @H.Pauwelyn 是吗?看到你还在使用地图视图可能就是这个原因。尝试使用支持片段更改代码,然后尝试链接中提到的相机工厂对象。你需要代码,所以我可以更新。
    【解决方案4】:

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

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

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

    • 必须拨打onCreate(),否则不会出现地图。

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

    所以,您在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();
        }
    }
    

    【讨论】:

      【解决方案5】:

      根据@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

      【讨论】:

        【解决方案6】:

        请先让您知道这一点。我将 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);
               }
         });
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-03
          • 1970-01-01
          相关资源
          最近更新 更多