How do I replace a fragment within a fragment?

I have an Activity with a ViewPager, each ViewPager has a Fragment.

Inside mine Screen3Fragment

, I have a LinearLayout ( lly_fragments

) where I am showing some other fragments. I start to show a snippetScreen3_1

public class Screen3Fragment extends Fragment {

    private FragmentManager manager;
    private FragmentTransaction transaction;


    public static Screen3Fragment newInstance() {
        final Screen3Fragment mf = new Screen3Fragment();
        return mf;
    }

    public Screen3Fragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_screen3, container, false);
        Screen3_1Fragment frag31 = new Screen3_1Fragment();
        manager = getChildFragmentManager();
        transaction = manager.beginTransaction();
        transaction.add(R.id.lly_fragments,frag31,"frag31");
        transaction.addToBackStack("frag31");
        transaction.commit();
        return v;
    }

}

      

This works great with no problem. The problem comes when from frag31

(which is inside the Screen3Fragment) I want to call fragt32

, for that I do the following.

public class Screen3_1Fragment extends Fragment {

    private ImageButton imgbt_timer;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_screen3_1,container,false);
        imgbt_timer = (ImageButton) v.findViewById(R.id.bT_scr31_timer);
        imgbt_timer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getChildFragmentManager().beginTransaction()
                                            .replace(R.id.lly_fragments, new Screen3_2Fragment(), "frag32")
                                            .commit();
            }
        });


        return v;
    }
}

      

As I read in other answers, the line transaction.replace

should do the trick and replace the existing one frag31

with the given one frag32

inside the same given container lly_fragments

.

However, I get java.lang.IllegalArgumentException: No view found for id.....

I'm not sure why.

+3


source to share


2 answers


getFragmentManager()

always returns the attributes from the parent, in most cases actions. getChildFragmentManager()

wil return the parent attributes (attributes in your case Screen3Fragment

). It should be used when you add a fragment inside a fragment.

In your case Screen3Fragment

, you should add with getFragmentManager()

and Screen3_1Fragment

should add with getChildFragmentManager()

, because it Screen3_1Fragment

is a Screen3Fragment

child. Screen3Fragment

is the parent.



I recommend that you always use getFragmentManager()

with a method add

, not replace

because your parent will be the same.

getChildFragmentManager()

can be used when you add the ViewPager inside a fragment.

0


source


You can use a callback like below: which worked for me, I hope my answers help you

1) create an interface

  public interface ChangeFragmentListener {

    void onChangeFragmentLicked(int fragment);
}

      

2) implement the interface and methods of transactions in your activity:



      public class MainActivity extends AppCompatActivity implements ChangeFragmentListener {


        FragmentTransaction fragmentTransaction;
        Fragment1 fragment1;
        Fragment2 fragment2;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);

            fragment1 = new Fragment1();
            fragment1.setChangeFragmentListener(this);

            fragment2 = new Fragment2();
            fragment2.setChangeFragmentListener(this);

            initListeners();
        }

    void changeToFrag1() {
            fragmentTransaction = getFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.activity_main_fragment_container,fragment1, "");
            fragmentTransaction.commit();
        }

        void changeToFrag2() {
            fragmentTransaction = getFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.activity_main_fragment_container, fragment2, "");
            fragmentTransaction.commit();
        }

@Override
    public void onChangeFragmentLicked(int fragment) {
        switch (fragment){
            case 1:
                changeToFrag1();
                break;

            case 2:
                changeToFrag2();
                break;
        }
    }

      

3) Create an object from the interface to handle the callback:

public class Fragment1 extends Fragment {

   private ChangeFragmentListener changeFragmentListener;

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

        view.findViewById(R.id.fragment1_textView).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeFragmentListener.onChangeFragmentLicked(2);
            }
        });

        return view;
    }

    public Fragment1 setChangeFragmentListener(ChangeFragmentListener changeFragmentListener) {
        this.changeFragmentListener = changeFragmentListener;
        return this;
    }
}

      

0


source







All Articles