【发布时间】:2012-12-07 06:11:41
【问题描述】:
如何使用(或“我们可以使用”)getChildFragmentManager() 以编程方式(动态)添加Fragments?
这是我的例子。
我有一个MainActivity、一个OuterFrag和一个InnerFrag。我将通过FragmentManager 动态地将OuterFrag 添加到MainActivity。此外,我还将通过FragmentManager 动态地将InnerFrag 添加到OuterFrag。但我想将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 的新孩子。这可以通过两个系统打印输出语句来验证之前:对象和之后:对象已更改。在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",并删除MainActivity.java中的第一个getSupportFragmentManager()语句)。它保持正确的层次结构:MainActivity -> OuterFrag -> InnerFrag。但原片段(outer_frag.xml)的文字永远不能被带走。
总之,我想在MainActivity 中始终引用OuterFrag。我希望OuterFrag 充当占位符来加载不同的InnerFrags。简而言之,我想在OuterFrag 中调用getChildFragmentManager(),当它以编程方式(动态)添加时。
【问题讨论】:
-
你搞定了吗?我的问题是你什么时候添加
InnerFrag,使它与OuterFrag的生命周期无缝匹配?
标签: android android-fragments android-nested-fragment