如何在片段内使用谷歌地图V2?

时间:2013-08-13 10:24:42

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

我有一个片段是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" />

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

9 个答案:

答案 0 :(得分:50)

为地图创建一个框架,在框架中将其添加到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)));
        }
    }

如果你们遇到任何问题非法状态异常发生,请写下面的代码

/ *      *此问题已被跟踪(Google Bugs)      * http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064已添加      *由于非法状态异常导致的代码在重新单击选项卡时发生      *      *为我修复它的短期解决方法是添加以下内容      *你调用的每个片段的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

答案 1 :(得分:12)

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

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

您可以按照this comment关于如何添加嵌套SupportMapFragment

答案 2 :(得分:7)

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

我跟着这个帖子(但是用西班牙语): https://groups.google.com/forum/#!msg/desarrolladores-android/1cvqPm0EZZU/Q801Yvb2ntYJ

线索是(在我看来)更改layout.xml文件: 而不是&#34;片段&#34;在你的&#34;布局subfragment_info.xml&#34;你需要改变这个:

<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

答案 3 :(得分:1)

我的方法是:

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);  

答案 4 :(得分:1)

对于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地图就会渲染

答案 5 :(得分:1)

在链接中,为您回答:

“问题在于你不应该做什么。你不应该在其他片段中膨胀片段。来自Android的文档:

注意:当布局包含a时,您无法将布局扩展为片段。只有动态添加到片段时才支持嵌套片段。

虽然您可以通过此处提供的黑客来完成任务,但我强烈建议您不要这样做。当你试图给包含另一个片段的片段的布局充气时,不可能确定这些黑客会处理每个新的Android操作系统所做的事情。

将片段添加到另一个片段的唯一Android支持方式是通过子片段管理器中的事务。“

对于这个问题:

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

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

答案 6 :(得分:1)

将负载映射到片段:

<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();
        }
    }
}

答案 7 :(得分:0)

我就这样做了

布局:

<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

答案 8 :(得分:0)

如果我用一个不同的片段替换地图片段所在的片段(在此代码示例中为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);
            }
    }

    }