2014-06-23 117 views
0

我有一个片段,它包含的XML是这样的:删除所有子片段

<RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="230dp"> 

     <fragment 
      android:id="@+id/myFragmen1" 
      android:name="com...widgets.myViewPager" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 

     <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/text""/> 

    </RelativeLayout> 

我需要在我的XML添加4个不同的片段。父母片段我开始像这样:

getFragmentManager().beginTransaction() 
      .replace(R.id.frameContainer, myFragment1) 
      .addToBackStack(null) 
      .commit(); 

所以,一切正常,直到我试图显示片段超过1次。如果我点击返回,并试图再次打开片段,然后我得到这些错误:

Caused by: java.lang.IllegalArgumentException: Binary XML file line #17: Duplicate id 0x7f080130, tag null, or parent id 0xffffffff with another fragment for com...widgets.myViewPager 

我知道的问题,也有一个解决方案。我可以删除onDestroy中的片段。但是,我不想这样做! 包含其他片段的xml是动态的。我通过这个包得到布局,所以在这个片段中,我不知道显示了哪个片段。如果我使用这部分超过一次,我必须确定,名称是一样的。所以我的问题是:有没有可能删除每个片段?所以每一个片段都会使自己和父母无关呢?

感谢您的帮助

编辑:

MyFragment myFragment1 = new MyFragment(); 

    Bundle bundle = new Bundle(); 
    bundle.putInt("layout",R.layout.my_fragment); 
    myFragment1.setArguments(bundle); 

    getFragmentManager().beginTransaction() 
      .replace(R.id.frameContainer, myFragment1) 
      .addToBackStack(null) 
      .commit(); 

这些电话,我从不同的地方做。对于每个调用,我可以用不同的片段创建自己的xml。 在我父片段我这样做:

int layoutId = this.getArguments().getInt("layout", 0); 
    if(layoutId==0) 
     throw new RuntimeException("LayoutId not found"); 

    return inflater.inflate(layoutId,container,false); 

这样做之后,我的片段加载XML与所有的碎片,这是我在XML设定。所以我可以从外部定义视图。从这个片段中摧毁并重新打开之后,它会抛出错误。这是因为我的xml中的所有片段都没有被销毁!我的父母片段不知道,哪些片段在xml中,所以我想,他们在课堂上摧毁自己。

+0

你在哪里与此达成? –

回答

2

发生此错误是因为子代Fragment s只能创建&以编程方式显示。 Fragment的XML布局不能包含<fragment ... />标记。从docs

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.

这里就是你需要做的:

STEP 1:修改父Fragment的XML布局如下:

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="230dp"> 

    <!-- <fragment 
     android:id="@+id/myFragmen1" 
     android:name="com...widgets.myViewPager" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> --> 

    <FrameLayout 
     android:id="@+android:id/childfragmentregion" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:padding="0dp" 
     android:layout_weight="1" > 
    </FrameLayout> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/text""/> 

</RelativeLayout> 

STEP 2 :然后,换一个新的小孩片段:

FragmentManager fm = getChildFragmentManager(); 
FragmentTransaction ft = fm.beginTransaction(); 
ft.replace(R.id.childfragmentregion, new SomeXYZFragment(), "some_xyz_fragment"); 
ft.commit(); 

第3步:如下重写你的父母FragmentonDetach()方法:

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

这将毫无例外工作。我请求你澄清你的问题的第二部分:我不清楚Fragment是否正在获取Bundle中的数据。如果你说得更清楚,我可以帮助你。

+0

感谢您的帮助,但我认为,这无济于事。也许我应该更好地解释它:我有4个片段,其中包含一个简单的内容,如2个Textviews,...下一个评论,对于一个评论来说太长了:) – user3621165

+0

现在我只需要制作一个xml,其中只包含我需要的片段。我是这样做的,因为我有一些不同的地方,我会从那里显示片段,但有另一个内容。所以我只是创建一个带有碎片的XML,并将这些XML放入捆绑包中。在开始片段加载不同片段的XML。所以我可以从外部处理视图的内容,但不必关心应该显示的数据。 – user3621165

+0

我只是指出了错误的原因,我认为这是正确的。我不太明白“将xml放在一个包中”的意思。你的意思是,我认为,你是在'Bundle'中的孩子'Fragment'中传递'TextView'的字符串*值*。 –