【问题标题】:android GoogleMap is null, displays fine but can't add markers/polylinesandroid GoogleMap 为空,显示正常但无法添加标记/折线
【发布时间】:2013-02-21 11:32:05
【问题描述】:

我有一个显示良好的 GoogleMap(在 SupportMapFragment 内)并使用 GoogleMapOptions 作为目标相机位置。但是,我无法向 GoogleMap 添加标记/折线。下面是创建地图的方法:

private void createMap(List<LatLng> latLngs) {

    if(map == null) {
        GoogleMapOptions options = new GoogleMapOptions();
        mapFragment = SupportMapFragment.newInstance(options);
        map = mapFragment.getMap();

        float zoom = 13;
        CameraPosition cameraP = new CameraPosition(latLngs.get(0), zoom, 0, 0);
        options.camera(cameraP);


        //TODO MAP IS NULL - SORT OUT!
        // check it has been instantiated
        if (map != null) {
            Log.d(TAG, "map is not null");
            map.clear();
            //Calculate target zoom, based on trip size
            map.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraP));
            // Add LatLngs to polyline

            PolylineOptions poly = new PolylineOptions().color(Color.RED);
            MarkerOptions startMarker = new MarkerOptions()
                    .position(latLngs.get(0)).title("Start");
            MarkerOptions endMarker = null;
            if(latLngs.size() > 1) {
             endMarker = new MarkerOptions().position(
                    latLngs.get(latLngs.size() - 1)).title("End");  
            }

            for (LatLng latLng : latLngs) {
                poly.add(latLng);
            }

            map.addPolyline(poly);
            map.addMarker(startMarker);
            map.addMarker(endMarker);

        }


        ft = getSupportFragmentManager().beginTransaction();
        ft.add(R.id.trip_summary_map_container, mapFragment);
        ft.commit();
    }
}

从内联 cmets 中可以看出,地图仍然为空(尽管它正在显示和使用选项)。只是不能添加东西。我假设我没有正确实例化它?

Activity 扩展了 FragmentActivity,我已经设置了使用 Maps API 所需的所有东西。

感谢您的帮助。

【问题讨论】:

    标签: android map null supportmapfragment


    【解决方案1】:

    编辑:我已经发布了new answer,其中包含我现在更喜欢使用的解决方案。

    几天前我遇到了同样的问题,我通过扩展 SupportMapFragment 类解决了它,以便在地图最终准备好后执行回调方法。

    public class ExtendedSupportMapFragment extends SupportMapFragment {
    
        public static interface MapReadyListener {
            public void mapIsReady(GoogleMap map);
        }
    
        @Deprecated
        public static SupportMapFragment newInstance() {
            return null;
        }
    
        @Deprecated
        public static SupportMapFragment newInstance(GoogleMapOptions options) {
            return null;
        }
    
        public static ExtendedSupportMapFragment newInstance(MapReadyListener mapReadyListener) {
            ExtendedSupportMapFragment fragment = new ExtendedSupportMapFragment();
            fragment.mapReadyListener = mapReadyListener;
    
            return fragment;
        }
    
        private MapReadyListener mapReadyListener;
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if (mapReadyListener != null)
                mapReadyListener.mapIsReady(getMap());
        }
    
    }
    

    那么你只需要这样做:

    public class RutaMapaFragment extends SherlockFragment implements ExtendedSupportMapFragment.MapReadyListener {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            fragmentMapa = ExtendedSupportMapFragment.newInstance(RutaMapaFragment.this);
        }
    
        ...
    
        @Override
        public void mapIsReady(GoogleMap map) {
            //Do whatever you want with your map.
        }
    
    }
    

    【讨论】:

    • 如此简单,实际上很明显,但在类似的问题上一直掉头发。效果很好!
    【解决方案2】:

    所以,时间已经过去了。事实是我不再使用my previous answer 中的解决方案,而是更喜欢使用ViewTreeObserver。以下代码显示了一个相当简单的片段,其中添加了 SupportMapFragment

    createMap() 方法添加了SupportMapFragment,然后执行setupMap(),但只能通过OnGlobalLayoutListener,它基本上会在地图实际准备好后执行。当然,这个监听器会立即被移除——没有必要再保留它了。

    public class MyMapFragment extends Fragment {
    
        private View mMapContainer;
        private SupportMapFragment mMapFragment;
        private GoogleMap mMap;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View view = inflater.inflate(/* ... */);
            // ...
    
            mMapContainer = view.findViewById(R.id.map_fragment_container);
            createMap();
    
            return view;
        }
    
        private void createMap() {
            mMapFragment = new SupportMapFragment();
    
            getFragmentManager().beginTransaction()
                    .replace(R.id.map_fragment_container, mMapFragment)
                    .commit();
    
            mMapContainer.getViewTreeObserver()
                    .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    
                        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                        @Override
                        public void onGlobalLayout() {
                            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
                                mMapContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                            } else {
                                mMapContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                            }
    
                            mMap = mMapFragment.getMap();
                            setupMap();
                        }
    
                    });
        }
    
        private void setupMap() {
            mMap.setMyLocationEnabled(true);
            // ...
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      尝试使用以下代码在地图中添加标记和折线:

      GoogleMap mMap;
      static final CameraPosition BONDI =
              new CameraPosition.Builder().target(new LatLng(-33.891614, 151.276417))
                      .zoom(15.5f)
                      .bearing(300)
                      .tilt(50)
                      .build();
      changeCamera(CameraUpdateFactory.newCameraPosition(BONDI));
          mMap.addMarker(new MarkerOptions().position(new LatLng(-33.891614, 151.276417)).title("Bondi"));
       private void changeCamera(CameraUpdate update) {
          changeCamera(update, null);
          }
      /**
       * Change the camera position by moving or animating the camera depending on the state of the
       * animate toggle button.
       */
      private void changeCamera(CameraUpdate update, CancelableCallback callback) {
          boolean animated = ((CompoundButton) findViewById(R.id.animate)).isChecked();
          if (animated) {
              mMap.animateCamera(update, callback);
          } else {
              mMap.moveCamera(update);
          }
      }
      

      如下添加折线:

       // A simple polyline with the default options from Melbourne-Adelaide-Perth.
          mMap.addPolyline((new PolylineOptions())
                  .add(BONDI));
      

      【讨论】:

      • 一切看起来都不错,但是在实现类似的东西之前,我的地图需要存在 - 它仍然是空的,并且不能被操纵。
      • 请检查您是否已在清单中定义了所有需要的权限和映射键。
      • 我有,当在活动的布局 xml 文件中包含地图片段时,我可以添加标记/折线,一切正常。但我想从 Web 服务加载 LatLngs(工作正常),并在加载 LatLngs 后以编程方式创建地图。地图是在加载后创建的,但它不会添加标记/折线,因为它是空的,因此无法操作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 2019-09-02
      相关资源
      最近更新 更多