5

我正在尝试在我的应用程序中使用新的 android 地图。

我有一个 FragmentActivity 布局包含(除其他外):

<LinearLayout a:id="@+id/fragment_container"
    a:layout_width="fill_parent"
    a:layout_height="100dp"
    a:layout_weight="1"/>

它还有一个按钮,可以使用(主要从示例项目复制)更改此片段:

if (condition) {
    fragment = new Fragment1();
} else {
    fragment = new LocationFragment();
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();

和 LocationFragment 是:

public class LocationFragment extends SupportMapFragment{
private GoogleMap mMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    view = inflater.inflate(R.layout.map_fragment, container, false);
    setUpMapIfNeeded();
    return view;
}

@Override
public void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment)  getActivity().getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
    mMap.addMarker(new MarkerOptions().position(new LatLng(60.02532, 30.370552)).title(getString(R.string.map_current_location)));
}
}

xml布局是:

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

问题是当我们第二次用 LocationFragment 替换 Fragment 时,android 无法从 xml 膨胀。它在线崩溃:

view = inflater.inflate(R.layout.map_fragment, container, false);

除了:

12-17 01:47:31.209: ERROR/AndroidRuntime(4679): FATAL EXCEPTION: main
    android.view.InflateException: Binary XML file line #4: Error inflating class fragment
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:587)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:386)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
    at my.package.LocationFragment.onCreateView(LocationFragment.java:29)
    ...

而且我不知道如何解决它。我认为这可能与您不能使用多个地图视图的旧问题有关(在 android map v1 上找到问题)。但是在 v2 和片段支持的情况下,它必须是用地图片段替换片段容器的方法,对吗?

4

3 回答 3

9

Remove your mapview fragment into onDestroyView method.

Fragment fragment = (getFragmentManager().findFragmentById(R.id.mapview));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
于 2013-10-29T12:18:30.733 回答
7

你正在扩展SupportMapFragment. 这很好,尽管我不确定这种模式会有多普遍(这有点太新了)。

但是,SupportMapFragment 它是一个片段,并且知道如何显示地图。在大多数情况下,您不应该onCreateView()覆盖,当然也不应该覆盖并尝试扩展onCreateView()包含<fragment>指向.SupportMapFragment

这是一个使用SupportMapFragmentMaps V2 库的示例应用程序。活动加载具有以下内容的布局SupportMapFragment

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.SupportMapFragment"/>
于 2012-12-16T22:16:57.297 回答
3

我没有扩展 SupportMapFragment ,而只是将其包含在使用 XML 的(常规)片段中,如上述答案中一样,但我得到了相同的结果... android.view.InflateException: Binary XML file line #4: Error inflating class when自发布以来,我第二次尝试为包含的片段充气。

我解决了这个问题,不是从 XML 中膨胀 MapFragment,而是在包含的片段 XML 中使用 FragmentLayout 留下一个占位符,然后在运行时以编程方式添加这个 MapFragment。完美运行。

包含片段 XML 看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- This is commented out because it crashed on second inflate.
    <fragment
        android:id="@+id/mapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginBottom="60dp"
        class="com.google.android.gms.maps.SupportMapFragment" />
    -->

    <FrameLayout
            android:id="@+id/mapFragmentHole"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_marginBottom="60dp"
            android:layout_gravity="center_vertical|center_horizontal" /> 
    .
    .
    .

然后在我的包含片段 java 代码中,我执行以下操作。这还展示了如何在 MapFragment 出现之前使用 GoogleMapOptions 对其进行配置。

_view = inflater.inflate(R.layout.fragment_map, container, false);

GoogleMapOptions gmo = (new GoogleMapOptions()).zoomControlsEnabled(false).rotateGesturesEnabled(false);
mapFragment = SupportMapFragment.newInstance(gmo);
FragmentTransaction fragmentTransaction = getFragmentManager()
        .beginTransaction();
fragmentTransaction.add(R.id.mapFragmentHole, mapFragment);
fragmentTransaction.commit();

在上面的代码中,mapFragment 是一个成员变量,所以我可以稍后访问它以获取 GoogleMap 对象,就像这样......

GoogleMap map = mapFragment.getMap();

但是,如果您在 onCreateView 中膨胀并执行 MapFragment 切换,您将无法在同一方法中获得有效的 GoogleMap 对象,因此您必须等到稍后再用数据填充地图。在我的代码中,我启动了一个后台线程来从我的 onCreateView 方法加载数据。加载数据后,它会在 UiThread 上调用一个方法来用工件填充地图。

希望这可以帮助。祝你好运!

-M。

于 2013-03-19T04:05:03.980 回答