在已创建父片段视图后添加嵌套片段 [英] Add Nested Fragment after Parent Fragment view is already created
问题描述
我正在尝试创建一个 Fragment,该 Fragment 具有将子 Fragment 添加到自身的公共方法.
I am trying to create a Fragment which has a public method for adding child Fragments to itself.
我一直在阅读可能类似的问题,但到目前为止还没有找到任何帮助.我已将问题简化为如下所示的简单测试应用程序.
I've been reading through potentially similar questions but haven't found anything to help so far. I've reduced the problem down to a simple test app shown below.
一旦 fragA
被添加到主布局,我调用公共方法 fragA.addFragB()
让它向自身添加一个 FragmentClassB 的实例,但是这会导致测试应用程序崩溃,表明活动已被破坏"(请参阅文章末尾的 LogCat).这是否意味着 fragA
已被销毁,因此我无法向其添加 fragB
,或者是否意味着 fragB
已被销毁,因此我可以't 将它添加到 fragA
吗?或者这完全是别的意思?
Once fragA
has been added to the main layout, I call the public method fragA.addFragB()
to get it to add an instance of FragmentClassB to itself, but this causes the test app to crash, indicating "Activity has been destroyed" (see LogCat at the end of the post). Does this mean fragA
has been destroyed so I can't add fragB
to it, or does it mean fragB
has been destroyed so I can't add it to fragA
? Or does it mean something else entirely?
MainActivity.java
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragMan = getSupportFragmentManager();
// add Fragment A to the main linear layout
FragmentTransaction fragTrans = fragMan.beginTransaction();
FragmentClassA fragA = new FragmentClassA();
fragTrans.add(R.id.mainLinearLayout, fragA);
fragTrans.addToBackStack("A");
fragTrans.commit();
// get Fragment A to add a Fragment B to itself
fragA.addFragB();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/mainLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
FragmentClassA.java
public class FragmentClassA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a, container, false);
}
public void addFragB() {
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
FragmentClassB fragB = new FragmentClassB();
childFragTrans.add(R.id.fragA_LinearLayout, fragB);
childFragTrans.addToBackStack("B");
childFragTrans.commit();
}
}
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragA_LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
FragmentClassB.java
public class FragmentClassB extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
}
fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
LogCat
11-18 16:17:05.627: E/AndroidRuntime(14351): FATAL EXCEPTION: main
11-18 16:17:05.627: E/AndroidRuntime(14351): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nestedfragmenttest/com.example.nestedfragmenttest.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.os.Handler.dispatchMessage(Handler.java:99)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.os.Looper.loop(Looper.java:137)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.main(ActivityThread.java:5103)
11-18 16:17:05.627: E/AndroidRuntime(14351): at java.lang.reflect.Method.invokeNative(Native Method)
11-18 16:17:05.627: E/AndroidRuntime(14351): at java.lang.reflect.Method.invoke(Method.java:525)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-18 16:17:05.627: E/AndroidRuntime(14351): at dalvik.system.NativeStart.main(Native Method)
11-18 16:17:05.627: E/AndroidRuntime(14351): Caused by: java.lang.IllegalStateException: Activity has been destroyed
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.example.nestedfragmenttest.FragmentClassA.addFragB(FragmentClassA.java:26)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.example.nestedfragmenttest.MainActivity.onCreate(MainActivity.java:25)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.Activity.performCreate(Activity.java:5133)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-18 16:17:05.627: E/AndroidRuntime(14351): ... 11 more
ianhanniballake 的回答和 GrIsHu 后来在同一点上展开的回答都有助于指出问题的根源.然而,这又引发了另一个问题.
最终目的是 FragmentClassA 将成为库的一部分.它将在多种情况下使用,并且 FragmentClassB 实例的数量会有所不同,甚至可能没有.因此,我需要能够从父活动触发将子片段添加到 FragmentClassA 的任何实例.我刚刚看了看将 fragA
作为 MainActivity
中的类级别变量,然后在 中调用
的 fragA.AddFragB()
>MainActivityonActivityCreated()
方法,但不可覆盖.有什么想法吗?
ianhanniballake's answer and GrIsHu's later answer which expands on the same point have both been helpful in pointing out the root of the problem. However this raises a further issue.
The final intention is that FragmentClassA will be part of a library. It will be used in multiple situations and the number of FragmentClassB instances will vary, or there may even be none. Hence I need to be able to trigger the addition of the child fragments to any instance of FragmentClassA from the parent activity. I've just had a look at keeping fragA
as a class level variable in MainActivity
and then calling fragA.AddFragB()
in the MainActivity
's onActivityCreated()
method, but it is not available to be overridden. Any thoughts?
推荐答案
FragA
中声明的片段不能直接加载.FragmentA 将首先加载,然后您可以通过从 fragA 的
onCreateView()
方法调用方法 addFragB()
来加载 FragmentB.
You can not directly load the fragment which you have declared in FragA
. The FragmentA will be loaded first and then after you can load the FragmentB by calling the method addFragB()
from your fragA's
onCreateView()
method.
尝试如下:
从您的 MainActivity
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragMan = getSupportFragmentManager();
// add Fragment A to the main linear layout
FragmentTransaction fragTrans = fragMan.beginTransaction();
FragmentClassA fragA = new FragmentClassA();
fragTrans.add(R.id.mainLinearLayout, fragA);
fragTrans.addToBackStack("A");
fragTrans.commit();
}
}
并尝试从 FragmentA
加载 FragmentB
如下:
And try to load the FragmentB
from FragmentA
as below:
public class FragmentClassA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
addFragB(); //Call and load fragment B here.
return inflater.inflate(R.layout.fragment_a, container, false);
}
public void addFragB() {
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
FragmentClassB fragB = new FragmentClassB();
childFragTrans.add(R.id.fragA_LinearLayout, fragB);
childFragTrans.addToBackStack("B");
childFragTrans.commit();
}
}
这篇关于在已创建父片段视图后添加嵌套片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!