Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace child Fragment dynamically from Child Fragment itself

I am using a Viewpager which naturally contain fragments. inside one of the fragments I have a sub fragment (child fragment) each child fragment contains a button which calls the following to replace the child fragment itself

FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
transaction.commit();

just to make it more visual:

1) is the parent fragment

2) is the child fragment. I need to replace the child fragment by pressing a button inside the child fragment itself

┌--------┐
|   1    |
| ┌-----┐|
| | 2   ||
| |     ||
| └-----┘|
└--------┘

Note: I know it is possible to replace the fragments using this approach, however, it seems that it is not possible to do this with child fragments as it throws following error.

java.lang.IllegalArgumentException: No view found for id 0x7f0f0104 (com.example.app:id/containerProfileDetails) for fragment ProfileDetailsAddressFragment

Update

Parent Fragment XML:

<LinearLayout 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:orientation="vertical"
android:gravity="center"
tools:context="com.example.app.fragments.ProfileDetailsFragment">

<TextView
    android:id="@+id/lbl_page"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="42sp"
    tools:text="2"
    android:visibility="gone"/>

<FrameLayout
    android:id="@+id/containerProfileDetails"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ></FrameLayout>
</LinearLayout>

Child Fragment 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"
tools:context="com.example.app.fragments.ProfileDetailsUserFragment">

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Fragment Profile User Details" />

<Button
    android:id="@+id/btnProfileDetailsUserNext"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"/>

</FrameLayout>

Parent Fragment Java:

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_details, container, false);
    lblPage = (TextView) view.findViewById(R.id.lbl_page);

    FragmentManager manager = getChildFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.containerProfileDetails, new ProfileDetailsUserFragment());
    transaction.commit();
    return view;
}

Child Fragment Java:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_profile_details_user, container, false);

    Button _btnProfileDetailsUserNext = (Button) v.findViewById(R.id.btnProfileDetailsUserNext);
    _btnProfileDetailsUserNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager manager = getChildFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
            transaction.commit();
        }
    });
    return v;
}
like image 887
Poorya Avatar asked Oct 18 '22 11:10

Poorya


2 Answers

Replace your Parent Fragment and Child Fragment Code with below

Parent_Fragment.Java

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_details, container, false);
    lblPage = (TextView) view.findViewById(R.id.lbl_page);

    FragmentManager manager = getChildFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.containerProfileDetails, new ProfileDetailsUserFragment());
    transaction.commit();
    return view;
}

Child_Fragment.Java

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_profile_details_user, container, false);

    Button _btnProfileDetailsUserNext = (Button) v.findViewById(R.id.btnProfileDetailsUserNext);
    _btnProfileDetailsUserNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager manager = getFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.containerProfileDetails, new ProfileDetailsAddressFragment());
            transaction.commit();
        }
    });
    return v;
}

I Have not tested the code, it may Produce some compilation error, but way is correct to implement.

like image 68
Aniruddh Parihar Avatar answered Oct 21 '22 03:10

Aniruddh Parihar


This will not work because in the Child Fragment, the fragment transaction is looking for a container with id R.id.containerProfileDetails. This container is not in the Child Fragment, but it is in the Parent Fragment.

What you need to do is to create a callback from the Child Fragment to the Parent Fragment. In the Onclick in your Child Fragment, call the callback to the Parent Fragment and then in the Parent Fragment, replace the Child Fragment with the desired Fragment.

like image 24
JaapM Avatar answered Oct 21 '22 03:10

JaapM