Add Nested Fragment after Parent Fragment view is already created
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.
Try out as below:
Remove the line fragA.addFragB();
from your 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(); }}
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(); }}
FragmentTransaction.commit
is not an immediate action as per the documentation therefore your fragA
is not attached to an Activity (hence why it returns that the activity is destroyed) when you call fragA.addFragB()
.
You should instead call addFragB()
in FragmentClassA.onCreate()
to ensure fragA
is attached to an activity and ready to initialize its own state.
Did you try adding this to child fragments:
@Override public void onDetach() { super.onDetach(); try { Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }
this will avoid runtime problems while switching between different fragments.
Let's say you have an activity with a Fragment, which will in turn have two child fragments: fragA
and FragB
.
You can implement child fragments something like this:
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.activity_mymessages, container, false); FragmentManager manager = getChildFragmentManager(); FragmentTransaction ft = manager.beginTransaction(); ft.replace(R.id.headlines, fragA); ft.replace(R.id.article, fragB); ft.commit(); return root;}
activity_mymessages.xml
<FrameLayout 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:gravity="center_horizontal"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <FrameLayout android:id="@+id/headlines" android:layout_height="match_parent" android:name="com.example.fragA" android:layout_width="103dp" android:layout_marginRight="10dp"/> <FrameLayout android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.fragB" android:layout_width="fill_parent" /> </LinearLayout></FrameLayout>
Let me know if this works, if not I can provide working code from my GitHub.