【问题标题】:"Duplicate id, tag null, or parent id 0x0 with another fragment" when adding second Fragment to ActionBarActivity将第二个 Fragment 添加到 ActionBarActivity 时,“与另一个片段重复 id、标记 null 或父 id 0x0”
【发布时间】:2014-03-28 02:17:58
【问题描述】:

当我尝试在我的主 ActionBarActivity 中添加新 Fragment 时,我收到“java.lang.IllegalArgumentException:二进制 XML 文件第 3 行:重复 id 0x7f05003f、标签 null 或父 id 0x0 与另一个片段”错误。

主要错误是 android.view.InflateException: Binary XML file line #3: Error inflating class fragment 错误,在我的 PlaceDetailsFragment 类的返回行上。

目标:在第一个 SupportMapFragment 之上获得第二个 Fragment,覆盖它约 30%。

main.java

public class Main extends ActionBarActivity{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        if (findViewById(R.id.fragment_container) != null) {

            if (savedInstanceState != null) {
                return;
            }

            FragmentTransaction mTransaction = getSupportFragmentManager()
                    .beginTransaction();
            SupportMapFragment mapFragmentSupportClass = new MapFragmentClass();
            mTransaction.add(R.id.fragment_container, mapFragmentSupportClass);
            mTransaction.commit();

            FragmentTransaction xTransaction = getSupportFragmentManager().beginTransaction();
            PlaceDetailsFragment placeDetailsFragment = new PlaceDetailsFragment();
            xTransaction.add(R.id.fragment_container, placeDetailsFragment);
            xTransaction.commit();
        }
    }

PlaceDetailsFragment.java 这是应用程序崩溃的地方,在返回线上。

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PlaceDetailsFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.details, container, false);

    }
}

main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/fragment_container"
             android:layout_width="match_parent"
             android:layout_height="match_parent" >

 </FrameLayout>

mapfragment.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"
          android:name="com.google.android.gms.maps.MapFragment"
/>

details.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android"

          android:layout_width="match_parent"
          android:layout_height="200dp"
          android:id="@+id/details"
          android:name="com.qstudios.whatsopenlate.PlaceDetailsFragment"
          android:tag="detailsTag"
/>

据我所知,我没有使用重复的 id 或标签,因此片段与 mapFragment、main 的 fragment_container 共享的父 id。为什么这是个问题。父母拥有相同的ID不是合乎逻辑吗?另外,这不是 NestedFragment,对吗?我正在使用 ActionBarActivity 和 FrameLayout 来放入片段。

这个错误已经停止了我 2 小时的工作效率,我在谷歌上找到的所有答案都是关于 ActionBarSherlock、嵌套片段等。没有人可以提供一个简单的解释或示例来说明如何适当地将 2 个片段放入框架布局。甚至https://developer.android.com/training/basics/fragments/fragment-ui.html 也没有解释如何做到这一点。

任何人对此有任何经验,并且知道我做错了什么以及如何解决它?

提前致谢!

【问题讨论】:

  • 在main中,如果将framelayout更改为relativelayout会发生什么? (或者,只是好奇,如果您尝试在地图片段之前添加详细信息片段会发生什么情况。您会得到相同的错误,但指向地图片段代码中的充气器吗?)
  • 只是好奇,如果将“fragment”标签替换为FrameLayout标签会怎样?
  • 为了排除重复的 ID,如果您将详细信息 ID 更改为会调用重建的 detailsXYZ 会发生什么
  • 查看生成的资源文件夹时(导航到 id),0x7f05003f 对应什么?
  • 当我有机会时,我可能会尝试复制你在我身上看到的问题。

标签: java android android-fragments android-actionbar illegalargumentexception


【解决方案1】:

正如您自己或多或少发现的那样,问题在于在 details.xml 中使用 &lt;fragment&gt; 标记的方式。根据安卓documentation

Activity 的布局 XML 可以包含 &lt;fragment&gt; 标签以在布局中嵌入片段实例。

基本上,您试图将标签用作片段的实际布局,而它的目的只是将现有片段(已经有自己的布局)嵌入到其他视图中。因此,正确的解决方案确实是为片段构建布局(例如 cmets 中提到的RelativeLayout),不使用&lt;fragment&gt;

如果您想将您创建的片段添加到其他布局(例如 main.xml),您可以使用&lt;fragment&gt; 来引用它。例如,main.xml 可以重写为:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <fragment
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:id="@+id/details"
        android:name="com.qstudios.whatsopenlate.PlaceDetailsFragment"
        android:tag="detailsTag" />

</FrameLayout>

在这种情况下,您可以从 main.java 中删除以下部分:

FragmentTransaction xTransaction = getSupportFragmentManager().beginTransaction();
PlaceDetailsFragment placeDetailsFragment = new PlaceDetailsFragment();
xTransaction.add(R.id.fragment_container, placeDetailsFragment);
xTransaction.commit();

但是,如果您选择使用 FragmentManager 以编程方式添加片段(就像您一样),则根本不需要使用该标签。

Fragments API 指南(特别是关于向活动添加片段的部分)中对此进行了很好的解释,我强烈建议您阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多