-1

我正在使用由 pete doyle 提供的 android support v4- google maps并试图删除一个 mapview 然后重新创建它,当我离开并返回它时,但我不断收到通常的 Java.lang.IllegalStateException: You are only允许在 MapActivity 中有一个 MapView。任何人都知道如何正确解决这个问题。我的片段中有这段代码。

分段:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    Log.d(TAG, "onCreate View called here in location fragment!!");

    if(view == null){
      view = inflater.inflate(R.layout.map, container, false);  

    frame = (FrameLayout)view.findViewById(R.id.mapContainer);
    //mapview = (MapView)view.findViewById(R.id.mapView);
    }

    if(mapview == null){

        mapview = new MapView(getActivity(), getActivity().getString(R.string.map_api_key));  // keep getting the error on this line
        mapview_is_active = true;
    }

    mapview.setClickable(true);
    mapview.setBuiltInZoomControls(true);
    mapview.setSatellite(true); // Satellite View
    mapview.setStreetView(true); // Street View
    mapview.setTraffic(true); // Traffic View

    frame.addView(mapview,0);



    //frame = (FrameLayout)view.findViewById(R.id.mapContainer);   
   return view;
}


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

       if(mapview == null){
           Log.d(TAG, "mapview is null here");
           mapview = new MapView(getActivity(), getActivity().getString(R.string.map_api_key));
       }

       if(frame.getChildAt(0) == null){
           Log.d(TAG, "mapview is null here in container");
           frame.addView(mapview);
       }

        MapController controller = mapview.getController();

        double lat = Double.parseDouble(longitude);
        double lon = Double.parseDouble(latitude);

        GeoPoint geopoint = new GeoPoint((int)(lat * 1E6), (int)(lon * 1E6));

        mapview.invalidate();

        List<Overlay> mapOverlays = mapview.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.map_point);
        AddMapOverlay add_map_overlay = new AddMapOverlay(drawable, getActivity());

        OverlayItem overlayitem = new OverlayItem(geopoint, name, address);

        add_map_overlay.addOverlay(overlayitem);

        mapOverlays.add(add_map_overlay);

        controller.animateTo(geopoint);
        controller.setZoom(15);
    }

在我的 onStop() 中:

 @Override
    public void onStop(){
        super.onStop(); 

        if(frame != null){
            frame.removeView(mapview); // i remove the mapview here
        }   
    }

这是我的 map.xml:

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/mapContainer"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:layout_weight="1">

</FrameLayout>

任何帮助将不胜感激。谢谢

4

4 回答 4

2

我用下面的代码做到了这一点。我的 FragmentActivity 中有一个 MapView 实例变量,然后在下面的 Fragment 本身中添加和删除它(仅包括相关部分):

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

    mLayoutMap = (FrameLayout) getActivity().findViewById(R.id.layoutMap);

    // create the map view if it's not already there
    if (((MyActivity)getActivity()).mMapView == null)
    {
        ((MyActivity)getActivity()).mMapView = 
                    new MapView(getActivity(), getActivity().getString(R.string.map_api_key));
        ((MyActivity)getActivity()).mMapView.setClickable(true);
    }

    // add the map view to the frame layout, at the lowest z-index
    mLayoutMap.addView(((MyActivity)getActivity()).mMapView, 0);

}

@Override
 public void onStop()
 {
     super.onStop();

     if (mLayoutMap.getChildCount() > 0 && mLayoutMap.getChildAt(0) instanceof MapView)
         mLayoutMap.removeViewAt(0);
 }

mLayoutMap 只是我的 XML 中的 FrameLayout。

于 2012-12-04T18:59:55.223 回答
1

通常我是这样做的(像你一样使用 android-support-v4-google_maps):

1) 使用 attachMap 和 detachMap 方法实现 IMapActivity 等活动接口

public class MyMapActivity extends FragmentActivity implements IMapActivity {
    private MapView mMapView;

    public void attachMap(ViewGroup mapHolder) {
        if (mMapView == null) {
            mMapView = getLayoutInflater().inflate(R.id.mapview, null);
        }

        mapHolder.addView(mMapView);
    }

    public void detachMap(ViewGroup mapHolder) {
        mapHolder.removeView(mMapView);
    }
}

2) 当需要在 Fragment.onDestroyView() 上附加 MapView 或分离 MapView 时调用该方法

public class MyMapFragment extends Fragment {
    private IMapActivity mMapViewHolder;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mMapViewHolder = (IMapActivity) activity;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mMapViewHolder.attachMap(getMapHolder());
    }

    @Override
    public void onDestroyView() {
        mMapViewHolder.detachMap(getMapHolder());
        super.onDestroyView();
    }
}

我将一些设置保存在一个单独的 xml MapView 中。当需要销毁Fragment时——分离MapView,在重新创建Fragment时附加MapView(你也可以在附加后更新MapView的控制器)。这允许我重用片段 MapView。

PS 我只是还没有找到任何方法来清理 MapViev 链接的 MapActivity。如果有办法,我将不胜感激。

于 2012-12-04T18:26:51.780 回答
0

尝试使用frame.removeAllViews()

于 2012-12-04T18:06:54.387 回答
0

如果您正在使用 navHost,则需要以编程方式而不是在 XML 中添加它,因为它会被复制。

 val mapFragment = SupportMapFragment.newInstance()
        requireActivity().supportFragmentManager
            .beginTransaction()
            .add(R.id.mapFragment, mapFragment)
            .commit()
于 2021-11-10T21:13:35.877 回答