【问题标题】:Android mapview with fragments can't be added twice?带有片段的Android mapview不能添加两次?
【发布时间】:2011-10-19 08:25:33
【问题描述】:

我正在使用带有 hack 的 android 兼容性类,以便在此处找到的片段中使用地图视图:https://github.com/petedoyle/android-support-v4-googlemaps

不幸的是,我发现如果 mapfragment 从 Activity 中删除,然后重新读取,我会收到“您只允许在 MapActivity 中有一个 MapView”错误。”

我理解错误背后的原理,并尝试在片段的onPause方法中破坏地图视图。不幸的是,我似乎无法完全破坏地图视图,因为我仍然得到它。我的代码如下所示:

private RelativeLayout layout; 
private MapView mp;

public void onResume(){
    super.onResume();
    Bundle args = getArguments();
    if(mp == null)
    {
        mp = new MapView(getActivity(), this.getString(R.string.map_api_key)); 
        mp.setClickable(true);
    }

    String request = args.getString("requestId");
    layout = (RelativeLayout) getView().findViewById(R.id.mapholder);
    layout.addView(mp);
    //TextView txt = (TextView) getView().findViewById(R.id.arguments);
    //txt.setText(request);
}

public void onPause(){
    super.onPause();
    layout.removeView(mp);
    mp = null;
}

有人对我在这里忽略破坏的参考有什么想法吗?

【问题讨论】:

    标签: android view android-mapview android-fragments


    【解决方案1】:

    我遇到了同样的问题。这是我解决它的方法:

    • 由于它应该只是 Activity 中 mapView 的一个实例,所以我在 Activity 的 onCreate 方法中对其进行了初始化:

      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          // initialize MapView programmatically to be used in Fragment :
          this.mActivityMapView = new MapView(MainActivity.this, getString(R.string.debug_mapview_apikey));
      
          setContentView(R.layout.activity_main);
      }
      
    • 然后我在片段的 onCreateView 方法中恢复它:

      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          this.mMapView = ((MainActivity) getActivity()).getMapView();
          return this.mMapView;
      }
      
    • 我在片段的 onDestroy 方法中销毁它:

      public void onDestroy() {
          NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
          parentView.removeView(this.mMapView);
          super.onDestroy();
      }
      

    【讨论】:

      【解决方案2】:

      您可能希望在 onPause 方法(而不是 onDestroy 方法)中删除地图视图

      public void onPause() {
          NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
          parentView.removeView(this.mMapView);
          super.onPause();}
      

      这样,您可以将 MapFragment 添加到 backstack。 (FragmentTransaction.addToBackStack 防止片段被破坏)

      【讨论】:

        【解决方案3】:

        Max 和 Bleeker 的答案效果很好,但如果你想支持屏幕方向更改,你需要特别小心,就像我一样。事实证明,当你旋转屏幕时,它会再次调用 OnCreateView 而不会调用 onPause 方法,从而添加了两次 mapview。为了修复它,在 OnCreateView 中我做了以下操作:

        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            this.mMapView = ((MyGameActivity) getActivity()).getMapView();
            if (this.mMapView.getParent()!=null)
            {
                NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
                parentView.removeView(this.mMapView);
            }
            return this.mMapView;
        }
        

        【讨论】:

          【解决方案4】:

          我试图找到一个简单的解决方案来解决这个问题。 在处理我的视图详细信息的类(RelativeLayout 扩展)上,我声明了一个private static MapView myMapView;。

          然后,重写 onFinishInflate() 方法,如下代码 sn-p:

              @Override
          protected void onFinishInflate() {  
              super.onFinishInflate();
          
              //myMapView = (MapView) findViewById(R.id.map_view);
              if (myMapView==null) 
                  myMapView = new MapView(context, getResources().getString(R.string.map_view_api_key));  
              if (myMapView.getParent() != null)
                  ((ViewGroup)myMapView.getParent()).removeView(myMapView);
          
              myMapView.setClickable(true);
              myMapView.setEnabled(true);
              RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
              myMapView.setLayoutParams(lp);          
              this.addView(myMapView);
          
          }
          

          这样你只有一个 MapView 实例。

          【讨论】:

            【解决方案5】:

            以下是我在 Fragment 的情况下解决此问题的方法。

            创建布局

             <LinearLayout
                    android:id="@+id/ll_mapcontainer"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical" />
            

            您可以在 XML 文件中任何您想要显示地图的地方放置类似布局

            现在代码将是这样的。

            package com.yuviii.sample;
            
            import android.content.Intent;
            import android.net.Uri;
            import android.os.Bundle;
            import android.support.v4.app.Fragment;
            import android.support.v4.app.FragmentManager;
            import android.view.LayoutInflater;
            import android.view.View;
            import android.view.ViewGroup;
            
            import com.google.android.gms.maps.GoogleMap;
            import com.google.android.gms.maps.SupportMapFragment;
            import com.google.android.gms.maps.model.LatLng;
            import com.google.android.gms.maps.model.MarkerOptions;
            import com.yuviii.sample.R;
            
            /**
             * Created by yubraj Poudel on 12/20/15.
             */
            public class ContactUsFragment extends Fragment  {
                static final LatLng PRACTICAL_ANSWER_LOCATION = new LatLng(53.558, 9.927);
                private SupportMapFragment fragment;
                private GoogleMap map;
            
                @Override
                public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                   View v = inflater.inflate(R.layout.page_contactus, container, false);
                    return v;
                }
            
            
            
                @Override
                public void onActivityCreated(Bundle savedInstanceState) {
                    super.onActivityCreated(savedInstanceState);
                                initializeMap();
                }
            
                private void initializeMap() {
            
                    FragmentManager fm = getChildFragmentManager();
                    fragment = (SupportMapFragment) fm.findFragmentById(R.id.ll_mapcontainer);
                    if (fragment == null) {
                        fragment = SupportMapFragment.newInstance();
                        fm.beginTransaction().replace(R.id.ll_mapcontainer, fragment).commit();
                    }
            
                }
                @Override
                public void onResume() {
                    super.onResume();
                    if (map == null) {
                        map = fragment.getMap();
                        map.addMarker(new MarkerOptions().position(PRACTICAL_ANSWER_LOCATION));
                    }
                }   
            }
            

            这对我有用。享受!!!

            【讨论】:

              猜你喜欢
              • 2014-11-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-06-04
              相关资源
              最近更新 更多