如何使用(或"我们可以使用")getChildFragmentManager()
以编程方式(动态)添加Fragment
吗?
以下是我的例子。
我有一个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();
}
}
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
的新子项。这可以通过两个System Print Out语句验证:Before:Object和After:Object被更改。在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()
{1}}中的{1}}语句。它保持了正确的层次结构:MainActivity.java
。但是原始片段(MainActivity -> OuterFrag -> InnerFrag
)的单词永远不能被删除。
总之,我想始终在outer_frag.xml
中引用OuterFrag
。我希望MainActivity
充当占位符来加载不同的OuterFrag
。简而言之,我想在InnerFrag
中调用getChildFragmentManager()
,当它以编程方式(动态)添加时。
答案 0 :(得分:45)
总之,我想总是在MainActivity中引用OuterFrag。 我希望OuterFrag充当占位符来加载不同的东西 InnerFrags。简而言之,我想调用getChildFragmentManager() OuterFrag,以编程方式(动态)添加。
如果你想要这个,那么让你的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
添加到主要活动的代码仍然有效。
答案 1 :(得分:-1)
如果您想在addInnerFrag()
代码中致电OuterFrag.java
,可以这样做:
<强> OuterFrag.java:强>
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
addInnerFrag();
}