使用GoogleMaps时,应用程序在替换FragmentManager时崩溃了[英] App crashes with FragmentManager Replace when using GoogleMaps

本文是小编为大家收集整理的关于使用GoogleMaps时,应用程序在替换FragmentManager时崩溃了的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在使用以下代码来加载片段,具体取决于在Navigation抽屉上选择了哪个项目,但是MapFragment在其内部包含Google Map片段,并且在尝试第二次打开后崩溃.

.

这是我正在使用的代码:

@Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        if (position == 0) {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, MapFragment.newInstance("a", "b"))
                    .commit();

        }
        else {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                    .commit();
        }
    }

这是日志:

03-01 14:18:25.870  27175-27175/com.br.appname E/﹕ Device driver API match
    Device driver API version: 23
    User space API version: 23
03-01 14:18:25.870  27175-27175/com.br.appname E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct 30 09:36:10 KST 2013
03-01 14:19:12.655  27175-27175/com.br.appname E/AndroidRuntime﹕ FATAL EXCEPTION: main
    android.view.InflateException: Binary XML file line #13: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f070055, tag null, or parent id 0x7f070054 with another fragment for com.google.android.gms.maps.MapFragment
            at android.app.Activity.onCreateView(Activity.java:4971)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
            at dalvik.system.NativeStart.main(Native Method)

这仅在mapfragment中发生.占位段效果很好.

更新

fragment_map.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.br.remotepark.fragments.MapFragment">

    <com.sothree.slidinguppanel.SlidingUpPanelLayout
        android:id="@+id/sliding_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom">

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#eee"
            android:orientation="vertical"
            android:clickable="true"
            android:focusable="false">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="68dp"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/name"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:textSize="14sp"
                    android:gravity="center_vertical"
                    android:paddingLeft="10dp" />

                <Button
                    android:id="@+id/follow"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:textSize="14sp"
                    android:gravity="center_vertical|right"
                    android:paddingRight="10dp"
                    android:paddingLeft="10dp" />

            </LinearLayout>
        </LinearLayout>

    </com.sothree.slidinguppanel.SlidingUpPanelLayout>

</RelativeLayout>

推荐答案

重复ID问题与使用嵌套片段的错误方式有关.

来自:版本/Android-4.2.html#NestedFragments

注意:当该布局包含<fragment>时,您不能将布局夸大成片段.嵌套片段仅在动态添加到片段时才能支持.

因此,您的fragment_map.xml不能直接包含com.google.android.gms.maps.MapFragment.用ID map_container替换为FrameLayout,然后尝试这样的东西:

public class MyFragmentWithMap extends Fragment {

    private MapFragment fragment;
    private GoogleMap map;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_map, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        FragmentManager fm = getChildFragmentManager();
        fragment = (MapFragment) fm.findFragmentById(R.id.map_container);
        if (fragment == null) {
            fragment = MapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map_container, fragment).commit();
        }
    }

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

    // ...
}

请注意使用getChildFragmentManager.

本文地址:https://www.itbaoku.cn/post/102536.html

问题描述

I'm using the following code to load fragments depending on which item has been selected on NavigationDrawer, however the MapFragment contains Google Maps fragment inside of it and it crashes after trying to open it for the second time.

Here's the code I'm using:

@Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        if (position == 0) {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, MapFragment.newInstance("a", "b"))
                    .commit();

        }
        else {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                    .commit();
        }
    }

And here's the log:

03-01 14:18:25.870  27175-27175/com.br.appname E/﹕ Device driver API match
    Device driver API version: 23
    User space API version: 23
03-01 14:18:25.870  27175-27175/com.br.appname E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct 30 09:36:10 KST 2013
03-01 14:19:12.655  27175-27175/com.br.appname E/AndroidRuntime﹕ FATAL EXCEPTION: main
    android.view.InflateException: Binary XML file line #13: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f070055, tag null, or parent id 0x7f070054 with another fragment for com.google.android.gms.maps.MapFragment
            at android.app.Activity.onCreateView(Activity.java:4971)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at com.br.appname.fragments.MapFragment.onCreateView(MapFragment.java:74)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
            at dalvik.system.NativeStart.main(Native Method)

This happens only with the MapFragment. PlaceholderFragment works just fine.

UPDATE

fragment_map.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.br.remotepark.fragments.MapFragment">

    <com.sothree.slidinguppanel.SlidingUpPanelLayout
        android:id="@+id/sliding_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom">

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#eee"
            android:orientation="vertical"
            android:clickable="true"
            android:focusable="false">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="68dp"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/name"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:textSize="14sp"
                    android:gravity="center_vertical"
                    android:paddingLeft="10dp" />

                <Button
                    android:id="@+id/follow"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:textSize="14sp"
                    android:gravity="center_vertical|right"
                    android:paddingRight="10dp"
                    android:paddingLeft="10dp" />

            </LinearLayout>
        </LinearLayout>

    </com.sothree.slidinguppanel.SlidingUpPanelLayout>

</RelativeLayout>

推荐答案

Duplicate ID issue is related to incorrect way of using nested fragments.

From: http://developer.android.com/about/versions/android-4.2.html#NestedFragments

Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically.

So your fragment_map.xml cannot directly contain com.google.android.gms.maps.MapFragment. Replace it with FrameLayout with id map_container and try something like this:

public class MyFragmentWithMap extends Fragment {

    private MapFragment fragment;
    private GoogleMap map;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_map, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        FragmentManager fm = getChildFragmentManager();
        fragment = (MapFragment) fm.findFragmentById(R.id.map_container);
        if (fragment == null) {
            fragment = MapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map_container, fragment).commit();
        }
    }

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

    // ...
}

Note the use of getChildFragmentManager.