在片段中使用谷歌地图:永远不会调用onMapReady

时间:2017-11-06 12:09:54

标签: android google-maps

我在另一个片段谷歌地图使用工作正常。因此,当我不得不为同一个应用程序中的另一个片段执行此操作时,我会复制/粘贴代码并调整充气器和findviewbyid。但是从不调用onMapReady(),因此googlemap保持为空。

我看过MapView.onMapReady never called in Fragment for load Google Map in MapView案例看起来与我的相似,但我想了解“实现OnMapReadyCallback”机制。

调用onMapReady的机制是什么?我想当调用mapView.getMapAsync(this)时会发生什么?

    import android.app.Fragment;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.ScrollView;
    import android.widget.TextView;
    import android.widget.Toast;

    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.MapView;
    import com.google.android.gms.maps.MapsInitializer;
    import com.google.android.gms.maps.OnMapReadyCallback;
    import com.google.android.gms.maps.model.BitmapDescriptorFactory;
    import com.google.android.gms.maps.model.CameraPosition;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.MarkerOptions;


    public class LocalisationMonitoringFragment extends Fragment implements OnMapReadyCallback {
        private Context context;
        private static View view;

        private MapView mapView;

        static private GoogleMap googleMap;

        public LocalisationMonitoringFragment() {
            // Required empty public constructor
        }

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

            view = inflater.inflate(R.layout.localization_monitor, null);

            mapView = (MapView) view.findViewById(R.id.loc_mapView);
            mapView.onCreate(savedInstanceState);
            mapView.onResume();
            mapView.getMapAsync(this);
            try {
         MapsInitializer.initialize(getActivity().getApplicationContext());
            } catch (Exception e) {
                e.printStackTrace();
            }

            return (view);

        }

   @Override
    public void onMapReady(GoogleMap map) {
        googleMap = map;
        LatLng sydney = new LatLng(latitude, longitude);
        googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));
        CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    }
我在布局文件中

<com.google.android.gms.maps.MapView
        android:id="@+id/loc_mapView"
        android:layout_below="@id/loc_name_txt"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp" />

2 个答案:

答案 0 :(得分:1)

首先,将View存储到static字段绝不是一个好主意。这同样适用于您的GoogleMap变量。

其次,在您从onResume()致电onCreate(Bundle)后,我不明白您应该立即致电mapView

也许onResume()来电可能已成为问题。

关于生命周期机制

这意味着(例如);您的片段中的onPause()方法应调用onPause()的{​​{1}}方法。

MapView

然后,您应该使用相同的逻辑实现其他生命周期方法:

  • @Override protected void onPause() { super.onPause(); this.mapView.onPause(); }
  • onDestroy()
  • onResume()
  • onLowMemory()
  • onSaveInstanceState()
  • onStop()

此外,当然,如果您尚未注册Google Maps API密钥,则您的地图将不会显示。所以一定要确保你也这样做了。你永远不会知道...

通过查看我的项目,其中onCreate(Bundle)位于MapView内,我看到我已经用这种方式覆盖了生命周期方法:

Fragment

不知道你的情况是否必要。我有几个案例@Override protected void onPause() { super.onPause(); if (this.mapView != null) this.mapView.onPause(); } 没有初始化并抛出MapView。没有它进行测试,如果有必要,添加NullPointerException检查。

此外,我实际上遗漏了以下方法:

  • null
  • onSaveInstanceState()
  • onStop()

它们是我的应用程序中一些崩溃的原因,所以我没有覆盖它们。

仍然,实施the docs说。如果你遇到一些问题,你可以尝试我做的事情。

此外,在onCreate(Bundle)我打电话

onCreateView(...)

之前

MapsInitializer.initialize(getContext());

我的this.mapView = (MapView) ...; 方法看起来像这样。

onCreateView(...)

虽然我对此表示怀疑,但上面提到的问题可能已经发生,因为我使用的是@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { this.rootView = inflater.inflate(R.layout.fragment_location, container, false); MapsInitializer.initialize(getContext()); this.mapView = (MapView) rootView.findViewById(R.id.map_view); this.mapView.onCreate(savedInstanceState); this.mapView.getMapAsync(this); // initialize other UI elements. return this.rootView; } 版本,而不是android.support.v4.app.Fragment版本。

答案 1 :(得分:0)

在我的片段xml中,我使用了以下内容:

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

在片段kt中,我使用了以下内容:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view: View = inflater.inflate(R.layout.fram_map_fragment, container, false)
    initMap(view, savedInstanceState)
    return view
}

private fun initMap(view: View?, savedInstanceState: Bundle?) {
    mapView = view?.findViewById(R.id.googleMap)
    mapView?.onCreate(savedInstanceState)
    mapView?.getMapAsync(this)
}

override fun onMapReady(map: GoogleMap?) {
    googleMap = map
    googleMap?.moveCamera(
        CameraUpdateFactory.newLatLngZoom(
            LatLng(lat, lng),
            17F
        )
    )
    googleMap?.mapType = GoogleMap.MAP_TYPE_SATELLITE
    googleMap?.setOnMapClickListener {
        // Create Marker
        drawMarkers(it)
    }
}

override fun onResume() {
    mapView?.onResume()
    super.onResume()
}

override fun onPause() {
    mapView?.onPause()
    super.onPause()
}

override fun onDestroy() {
    mapView?.onDestroy()
    super.onDestroy()
}

override fun onLowMemory() {
    mapView?.onLowMemory()
    super.onLowMemory()
}

它运行完美