Fragment Inside Fragment
I needed some more context, so I made an example to show how this is done. The most helpful thing I read while preparing was this:
- Creating and Using Fragments
Activity
activity_main.xml
Add a FrameLayout
to your activity to hold the parent fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity"/>
<FrameLayout
android:id="@+id/parent_fragment_container"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
MainActivity.java
Load the parent fragment and implement the fragment listeners. (See fragment communication.)
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements ParentFragment.OnFragmentInteractionListener, ChildFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Begin the transaction
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.parent_fragment_container, new ParentFragment());
ft.commit();
}
@Override
public void messageFromParentFragment(Uri uri) {
Log.i("TAG", "received communication from parent fragment");
}
@Override
public void messageFromChildFragment(Uri uri) {
Log.i("TAG", "received communication from child fragment");
}
}
Parent Fragment
fragment_parent.xml
Add another FrameLayout
container for the child fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:background="#91d0c2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Parent fragment"/>
<FrameLayout
android:id="@+id/child_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
ParentFragment.java
Use getChildFragmentManager
in onViewCreated
to set up the child fragment.
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
public class ParentFragment extends Fragment {
private OnFragmentInteractionListener mListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_parent, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Fragment childFragment = new ChildFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.child_fragment_container, childFragment).commit();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void messageFromParentFragment(Uri uri);
}
}
Child Fragment
fragment_child.xml
There is nothing special here.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:background="#f1ff91">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Child fragment"/>
</LinearLayout>
ChildFragment.java
There is nothing too special here, either.
import android.support.v4.app.Fragment;
public class ChildFragment extends Fragment {
private OnFragmentInteractionListener mListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_child, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void messageFromChildFragment(Uri uri);
}
}
Notes
- The support library is being used so that nested fragments can be used before Android 4.2.
AFAIK, fragments cannot hold other fragments.
UPDATE
With current versions of the Android Support package -- or native fragments on API Level 17 and higher -- you can nest fragments, by means of getChildFragmentManager()
. Note that this means that you need to use the Android Support package version of fragments on API Levels 11-16, because even though there is a native version of fragments on those devices, that version does not have getChildFragmentManager()
.