【问题标题】:How to use google map V2 inside fragment?如何在片段中使用谷歌地图 V2?
【发布时间】:2013-08-14 22:09:04
【问题描述】:

我有一个片段,它是 Viewpager 的一部分,我想在该片段中使用 Google Map V2。这是我迄今为止尝试过的,

在我的片段中,

    private SupportMapFragment map;
      private GoogleMap mMapView;

   @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        FragmentManager fm = getChildFragmentManager();
        map = (SupportMapFragment) fm.findFragmentById(R.id.map);
        if (map == null) {
            map = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map, map).commit();
        }



    }

    @Override
    public void onResume() {
        super.onResume();
        if (mMapView == null) {
            mMapView = map.getMap();
            Marker hamburg = mMapView.addMarker(new MarkerOptions().position(HAMBURG)
                      .title("Hamburg"));
                  Marker kiel = mMapView.addMarker(new MarkerOptions()
                      .position(KIEL)
                      .title("Kiel")
                      .snippet("Kiel is cool")
                      .icon(BitmapDescriptorFactory
                          .fromResource(R.drawable.ic_launcher)));


                  mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

                  // Zoom in, animating the camera.
           mMapView.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);


        }
    }

在我的布局 subfragment_info.xml 中,我有,

<fragment
            android:id="@+id/map"
            class="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/tableLayout1" />

我现在可以看到地图了。但是标记没有显示。我认为我的谷歌地图 mMapView 是空的。请帮我解决这个问题。提前致谢。

【问题讨论】:

    标签: android google-maps-android-api-2


    【解决方案1】:

    我就是这样做的

    在布局中:

    <fragment 
        android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout_weight=".90"
          class="com.google.android.gms.maps.SupportMapFragment"
          />
    

    在代码中:

    public class GPS extends FragmentActivity {
    
    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }
    
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (supportMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            supportMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (supportMap != null) {
                MarkerOptions mo = new MarkerOptions().position( new LatLng( latitude, longitude ) );
                supportMap.addMarker( mo );
            }
        }
    }
    }
    

    花了我很多时间,你需要正确的组合,确保你的类扩展了 FragmentActivity

    【讨论】:

    • 谢谢哥们,其实我用的是Fragment。不是活动。这个解决方案适用于片段吗?
    【解决方案2】:

    您必须决定是在代码new SupportMapFragment() 中创建片段还是从xml class="com.google.android.gms.maps.SupportMapFragment" 膨胀。

    实际上,您不能在 xml 中为另一个 Fragment 使用 Fragment。阅读nested Fragments。

    您可以关注this comment,了解如何添加嵌套SupportMapFragment。

    【讨论】:

      【解决方案3】:

      我的做法是:

      Bundle bundle = new Bundle();
      bundle.putInt(MY_ID, id);
      
      FragmentManager fm  = getFragmentManager();
      Fragment fragment = fm.findFragmentById(R.id.customer_details_fragment);
      
      fragment = new SalesFragment();
      fm.beginTransaction()
        .add(R.id.customer_details_fragment, fragment)
        .commit();
      
      fragment.setArguments(bundle);  
      

      【讨论】:

      • 谢谢,但您正在使用 Activity。我的是片段。
      • 是的,我正在改变它。
      【解决方案4】:

      为地图创建一个框架,将其添加到您的 xml 布局中

      <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/map_container">
      
      <!-- The map fragments will go here --> 
      </RelativeLayout>
      

      不要在 xml 中包含 class="com.google.android.gms.maps.SupportMapFragment" 在您的片段类中,请在 onActivityCreated 中手动获取它

          @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          FragmentManager fm = getChildFragmentManager();
          fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
          if (fragment == null) {
              fragment = SupportMapFragment.newInstance();
              fm.beginTransaction().replace(R.id.map_container, fragment).commit();
          }
      
      
      /***at this time google play services are not initialize so get map and add what ever you want to it in onResume() or onStart() **/
      }
      
      @Override
          public void onResume() {
              super.onResume();
              if (map == null) {
                  map = fragment.getMap();
                  map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
              }
          }
      

      如果你们遇到任何问题 Illegal State Exception Occur 只需写下面的代码

      /* * 这个问题在 (Google Bugs) 中被追踪 * http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064 已添加 * 重新点击选项卡时出现非法状态异常代码 * *为我修复它的短期解决方法是将以下内容添加到 * 你调用的每个 Fragment 的 onDetach() */

      @Override
          public void onDetach() {
              super.onDetach();
      
              try {
                  Field childFragmentManager = Fragment.class
                          .getDeclaredField("mChildFragmentManager");
                  childFragmentManager.setAccessible(true);
                  childFragmentManager.set(this, null);
      
              } catch (NoSuchFieldException e) {
                  throw new RuntimeException(e);
              } catch (IllegalAccessException e) {
                  throw new RuntimeException(e);
              }
          }
      

      //如果你想在活动中显示地图,只需通过 //FragmentActivity 编写下面提到的代码来扩展你的活动

      在 onCreate 中

      FragmentManager fm = getSupportFragmentManager();
              fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
              if (fragment == null) {
                  fragment = SupportMapFragment.newInstance();
                  fm.beginTransaction().replace(R.id.map_container, fragment)
                          .commit();
          }
      

      在 onResume 中

      @Override
          protected void onResume() {
              super.onResume();
              if (googleMap == null) {
                  initilizeMap();
      
              }
          }
      
      private void initilizeMap() {
              if (googleMap != null) {
      
                  googleMap = fragment.getMap();
                  googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                  googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                  googleMap.getUiSettings().setCompassEnabled(true);
                  googleMap.getUiSettings().setRotateGesturesEnabled(true);
      
                  CameraPosition cameraPosition = new CameraPosition.Builder()
                          .target(new LatLng(latitude, longitude)).zoom(10).build();
                  googleMap.animateCamera(CameraUpdateFactory
                          .newCameraPosition(cameraPosition));
      
                  // create marker
                  MarkerOptions marker = new MarkerOptions().position(new LatLng(
                          latitude, longitude));
                  // ROSE color icon
                  marker.icon(BitmapDescriptorFactory
                          .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
                  // adding marker
                  googleMap.addMarker(marker);
      
                  // check if map is created successfully or not
                  if (googleMap == null) {
                      Toast.makeText(getApplicationContext(),
                              "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                              .show();
                  }
              }
          }
      

      可以从这些链接获得更多帮助
      https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1 https://developers.google.com/maps/documentation/android/map

      【讨论】:

      • 完美运行!非常感谢!
      • 感谢您对我的回答的支持。我只回答我在开发应用程序过程中实施的那些问题。 @快乐发展
      • 找不到 getMap();
      • @SagarDevanga 这是我们想要在片段中显示地图时的代码。你在做片段吗?
      • 是的,我也找到了为什么 getMap 不可用的答案。这是因为地图是动态生成的,所以在地图可用之前 getMap 方法不可用。由于在我们编写代码时它不可用,这就是 getMap 不可用的原因。
      【解决方案5】:

      对于 MapFragment

       <fragment
          android:id="@+id/map"
          android:name="com.google.android.gms.maps.MapFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
      

      在您的片段类中

      map = ((MapFragment) getActivity().getFragmentManager()
                  .findFragmentById(R.id.map)).getMap();
          map.addMarker(new MarkerOptions().position(
                  new LatLng(13.031902, 80.278823)).title("Marker Title"));
      

      对于 SupportMapFragment

      <fragment
          android:id="@+id/map"
          android:name="com.google.android.gms.maps.SupportMapFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
      

      在您的片段类中

      map = ((SupportMapFragment) getActivity().getSupportFragmentManager()
                  .findFragmentById(R.id.map)).getMap();
          map.addMarker(new MarkerOptions().position(
                  new LatLng(13.031902, 80.278823)).title("Marker Title"));
      

      注意 - 一旦用户触摸地图,SupportMapFragment 地图就会呈现

      【讨论】:

        【解决方案6】:

        我或多或少有同样的问题。我有一个导航抽屉,我想把地图放在一个片段中。

        我关注了这个帖子(但它是西班牙语的): https://groups.google.com/forum/#!msg/desarrolladores-android/1cvqPm0EZZU/Q801Yvb2ntYJ

        线索是(在我看来)更改 layout.xml 文件: 而不是“布局 subfragment_info.xml”中的“片段”,您需要更改为:

        <com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />`
        

        这是线程内的代码(您可以使用它并进行调整): https://groups.google.com/d/msg/desarrolladores-android/1cvqPm0EZZU/9srw_9feamUJ

        【讨论】:

        • 感谢您的解决方案。我也在使用导航抽屉,我想要一个单独的地图片段。使用您的解决方案,我设法使其正常工作。此解决方案还修复了更改屏幕方向时的一些奇怪错误(地图不显示/渲染,但只有其上的标记)
        【解决方案7】:

        在链接中,为你解答:

        “问题是你试图做的事情不应该做。你不应该在其他片段中膨胀片段。来自Android的文档:

        注意:当布局包含 .只有动态添加到片段时才支持嵌套片段。

        虽然您可以使用此处介绍的技巧完成任务,但我强烈建议您不要这样做。当您尝试为包含另一个 Fragment 的 Fragment 扩展布局时,无法确保这些 hack 能够处理每个新的 Android 操作系统所做的事情。

        将片段添加到另一个片段的唯一 Android 支持的方法是通过来自子片段管理器的事务。”

        对于这个问题:

        Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment

        对我来说,最好的解决方案是@DeepakPanwar

        【讨论】:

          【解决方案8】:

          如果我用不同的片段替换地图片段所在的片段(在此代码示例 MyFragment 中)然后返回,我会收到 IllegalStateException

          public class Home_Map extends Fragment {
          
          GoogleMap googleMap;
          FragmentManager myFragmentManager;
          SupportMapFragment mySupportMapFragment;
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                  Bundle savedInstanceState) {
              // TODO Auto-generated method stub
               View rootView = inflater.inflate(R.layout.fragment_home__map, container, false);
          
               //googleMap.setMyLocationEnabled(true);
          
                  try {
                      // Loading map
                      initilizeMap();
                      googleMap.setMyLocationEnabled(true);
          
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              return rootView;
          }
           private void initilizeMap() {
          
                  try
                  {
                  if (googleMap == null) {
                      myFragmentManager = getFragmentManager();
                      mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map2);
                      googleMap = mySupportMapFragment.getMap();
          
                      if (googleMap == null) {
                          Toast.makeText(getActivity().getApplicationContext(),
                                  "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                                  .show();
                      }
                  }
                  } catch (Exception e) { Toast.makeText(getActivity().getApplicationContext(), ""+e, 1).show();
                      // TODO: handle exception
                  }
              }
          
             @Override
              public void onResume() {
                  super.onResume();
          
                  initilizeMap();
          
              }
          
             @Override
              public void onDetach() {
                  // TODO Auto-generated method stub
                  super.onDetach();
                    try {
                          Field childFragmentManager = Fragment.class
                                  .getDeclaredField("mChildFragmentManager");
                          childFragmentManager.setAccessible(true);
                          childFragmentManager.set(this, null);
          
                      } catch (NoSuchFieldException e) {
                          throw new RuntimeException(e);
                      } catch (IllegalAccessException e) {
                          throw new RuntimeException(e);
                      }
              }
          
              }
          

          【讨论】:

            【解决方案9】:

            将地图加载到片段中:

            <fragment
                android:id="@+id/fragmentMap1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                class="com.google.android.gms.maps.SupportMapFragment"/>
            

            对于.java:

            public class PathFragment extends Fragment {
                View view;
                GoogleMap mMap;
                @Nullable
                @Override
                public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                    view=inflater.inflate(R.layout.fragment_path,null);
                     setupMap();
                    return view;
                }
            
                private void setupMap()
                {
                    if (mMap == null)
                    {
                        mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_map1)).getMap();
                        mMap.getUiSettings().setZoomControlsEnabled(true);
                    }
            
                    mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                        @Override
                        public void onMapLoaded() {
                            getlocation();
                        }
                    });
                }
            
                public void getlocation()
                {
                    try
                    {
                        /*Collect Source and destination latitude and longitude
                        * To draw Polyline
                        * */
            
                        LatLng src = new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lng()));
                        LatLng dest =new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lng()));
            
                        //Add Marker
                        mMap.addMarker(new MarkerOptions()
                            .position(src)
                            .title("Source")
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.srcicon)));
            
            
                        mMap.addMarker(new MarkerOptions()
                            .position(dest)
                            .title("Destination")
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.desticon)));
            
            
            
                        Polyline line = mMap.addPolyline(
                            new PolylineOptions().add(
                                new LatLng(src.latitude, src.longitude),
                                new LatLng(dest.latitude, dest.longitude)
                            ).width(5).color(Color.RED).geodesic(true)
                        );
            
                        //set zoom level
                        LatLngBounds.Builder builder = new LatLngBounds.Builder();
                        builder.include(src);
                        builder.include(dest);
                        LatLngBounds bounds = builder.build();
            
                        int padding = 0; // offset from edges of the map in pixels
                        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
                        mMap.animateCamera(cu);
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多