getChildFragmentManager()以编程方式(dynamic)添加碎片?

如何使用(或“我们可以使用”) getChildFragmentManager()以编程方式(dynamic)添加Fragment s?

这是我的例子。

我有一个MainActivity ,一个OuterFrag和一个InnerFrag 。 我将通过FragmentManagerdynamic地将OuterFrag添加到MainActivity 。 而且,我也会通过FragmentManagerdynamic地将OuterFrag添加到InnerFrag 。 但是我想添加InnerFrag作为InnerFrag一个子OuterFrag ,而不是replaceOuterFrag并成为MainActivity的新子OuterFrag

我想要保持这个层次结构: MainActivity -> OuterFrag -> InnerFrag 所以MainActivity总是可以调用OuterFrag。

但是不要从这个层次结构改变: MainActivity -> OuterFrag到这个层次结构: MainActivity -> InnerFrag MainActivity会丢失OuterFrag

这是我的示例代码。

MainActivity.java

 package com.example.frag; import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit(); getSupportFragmentManager().executePendingTransactions(); System.out.println("Before: " + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); ((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout)) .addInnerFrag(); System.out.println("After: " + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); } } 

activity_main.xml中

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

OuterFrag.java

 package com.example.frag; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class OuterFrag extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.outer_frag, container, false); } public void addInnerFrag() { getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit(); getFragmentManager().executePendingTransactions(); // getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit(); // getChildFragmentManager().executePendingTransactions(); } } 

outer_frag.xml

 <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="i am the OUTER frag" /> 

InnerFrag.java

 package com.example.frag; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class InnerFrag extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.inner_frag, container, false); } } 

inner_frag.xml

 <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="i am the INNER frag" /> 

目前,上面的代码可以运行没有错误。 但实际上它正在将InnerFrag作为MainActivity的新孩子。 这可以通过Before:Object和After:Object更改的两个System Print Out语句来validation。 在OuterFrag.java ,如果运行getChildFragmentManager()语句而不是getFragmentManager()语句,我们将得到以下运行时错误:

 12-07 02:29:38.406: E/AndroidRuntime(12051): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000} 

使用getChildFragmentManager()在理论上是正确的。 它可以用于非编程添加的片段(意味着将activity_main.xml<FrameLayout>更改为<fragment> ,添加属性android:name="com.example.frag.OuterFrag" ,并移除第一个getSupportFragmentManager() MainActivity.java语句)。 它保持正确的层次结构: MainActivity -> OuterFrag -> InnerFrag 。 但是原始片段( outer_frag.xml )的单词永远不能被带走。

总之,我想总是在MainActivity引用OuterFrag 。 我想OuterFrag充当一个占位符来加载不同的InnerFrag 。 简而言之,我想调用OuterFrag getChildFragmentManager() ,当它以编程方式(dynamic)添加。

Solutions Collecting From Web of "getChildFragmentManager()以编程方式(dynamic)添加碎片?"

总之,我想总是在MainActivity中引用OuterFrag。 我想OuterFrag作为一个占位符来加载不同的InnerFrags。 简而言之,我想调用OuterFrag中的getChildFragmentManager(),当它以编程方式(dynamic)添加。

如果你想要这个,那么你的OuterFrag就有一个容器布局作为它的内容,并且把InnerFrag添加到那个容器中。 OuterFrag的布局文件将是:

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

当然你可以在OuterFrag的布局中有其他的视图,如果你想的话。 那么你的addInnerFrag方法将是:

 public void addInnerFrag() { getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit(); getChildFragmentManager().executePendingTransactions(); } 

OuterFrag添加到主活动的代码仍然有效。

如果你想在你的OuterFrag.java代码中调用addInnerFrag() ,你可以这样做:

OuterFrag.java:

 @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); addInnerFrag(); }