如何在以getChildFragmentManager()
编程方式(动态)添加Fragment
的 s 上使用(或“我们可以使用”)?
这是我的例子。
我有一个MainActivity
,一个OuterFrag
,还有一个InnerFrag
。我将OuterFrag
通过. 而且,我将通过. 但我想完全添加为 的孩子,而不是替换并成为.MainActivity
FragmentManager
InnerFrag
OuterFrag
FragmentManager
InnerFrag
OuterFrag
OuterFrag
MainActivity
我想保持这个层次结构: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();
}
}
外部碎片.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
。这可以通过两个系统打印输出语句来验证之前:对象和之后:对象已更改。在 中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
's更改<FrameLayout>
为<fragment>
、添加属性android:name="com.example.frag.OuterFrag"
并删除 中的第一条getSupportFragmentManager()
语句MainActivity.java
)。它保持正确的层次结构:MainActivity -> OuterFrag -> InnerFrag
. 但原片断(outer_frag.xml
)的文字是永远不能被带走的。
总之,我想总是参考OuterFrag
。MainActivity
我想OuterFrag
充当一个占位符来加载不同InnerFrag
的s。简而言之,当它以编程方式(动态)添加时getChildFragmentManager()
,我想调用它。OuterFrag