3

I am rather new to android development and have a problem with the invocation/replacement of fragments. My issue is very similar to this one: Android - fragment .replace() doesn't replace content - puts it on top. The "solution" to this was however, that the fragment had to be created in the code and not in the xml-file.

I now have the same problem but my fragment is created dynamically in the code (MainActivity.java):

public void selectDrawerItem(MenuItem menuItem) {

    Fragment fragment = null;
    Class fragmentClass;
    switch(menuItem.getItemId()) {
        case R.id.nav_first_fragment:
            fragmentClass = FirstFragment.class;
            break;
        case R.id.nav_second_fragment:
            fragmentClass = SecondFragment.class;
            break;
        case R.id.nav_third_fragment:
            fragmentClass = ThirdFragment.class;
            break;
        default:
            fragmentClass = FirstFragment.class;
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e){
        e.printStackTrace();
    }

    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).addToBackStack(null).commit();

    menuItem.setChecked(true);
    setTitle(menuItem.getTitle());

    mDrawer.closeDrawers();
}

Now when i try to let that Fragment invoke a different Fragment and replace its own content with that of the new one, it just adds its content below the already existing one instead of replacing it.

My FirstFragment.java:

public class FirstFragment extends Fragment {

private View v;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    v = inflater.inflate(R.layout.content_first,container, false);
    configureImageButton();
    return v;
}

private void configureImageButton() {
    // TODO Auto-generated method stub
    ImageButton btn = (ImageButton) v.findViewById(R.id.imageButton1);

    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(), "You Clicked the button!", Toast.LENGTH_LONG).show();

            Fragment f1 = null;
            Class c;
            c = FirstFirstFragment.class;

            try {
                f1 = (Fragment) c.newInstance();
            } catch (IllegalAccessException e){
                e.printStackTrace();
            } catch (java.lang.InstantiationException e){
                e.printStackTrace();            }


            FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.tableLayout1, f1);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();

        }
    });

}

And my FirstFirstFragment.java:

public class FirstFirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.content_first_first, container, false);
    return view;
}

My activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- This DrawerLayout has two children at the root  -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- This LinearLayout represents the contents of the screen  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- The ActionBar displayed at the top -->
        <include
            layout="@layout/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <!-- The main content view where fragments are loaded -->
        <FrameLayout
            android:id="@+id/flContent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <Switch
                android:id="@+id/switch1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </FrameLayout>
    </LinearLayout>

    <!-- The navigation drawer that comes from the left -->
    <!-- Note that `android:layout_gravity` needs to be set to 'start' -->
    <android.support.design.widget.NavigationView
        android:id="@+id/nvView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@android:color/white"
        app:menu="@menu/drawer_view"
        app:headerLayout="@layout/nav_header"/>
</android.support.v4.widget.DrawerLayout>

I read in the answers of the article i linked at the beginning that someone had this exact problem and solved it by using the same FragmentManager. Just like me, he had used getSupportFragmentManager() in his Activity and getFragmentManager() in his Fragment before.

But the Fragment does not know getSupportFragmentManager(), so how is that supposed to work?

I tried everything i know of to resolve this issue but nothing worked. Then i read this

As far as i know you cannot add fragments into fragments.In design document it's written that "A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle." So your design seems like impossible to develop for now.

on a similar question on stackoverflow and am now wondering: Is it even possible to let a fragment invoke another fragment which then replaces the first one?(and not just adds it below)

I really hope this question is reasonable and not some stupid beginner's mistake because i searched the whole internet and did not find a proper answer.

Thanks in advance for your kind answers :).

  • `getActivity().getSupportFragmentManager()` – Pavneet_Singh May 13 '18 at 15:30
  • Thanks for the fast answer, but i did try that already and even though i am able to call the getSupportFragmentManager()-method from my Fragment, it still places its content below the already existing one instead of replacing it.... – P. Stephani May 13 '18 at 15:33
  • post your activity layout xml file – Pavneet_Singh May 13 '18 at 15:34
  • getChildSupportFragment inside fragment class – Hardik Vasani May 13 '18 at 15:36
  • @HardikVasani read the bold text in question carefully – Pavneet_Singh May 13 '18 at 15:39
  • I'm not sure I understood your question. You'd like to replace FirstFragment, when you click the button with a new instance of FirstFragment, but it doesn't replace just add the new instace of FirstFragment? – user3057944 May 13 '18 at 16:10
  • No i would like the FirstFirstFragment.java to replace FirstFragment.java with the click of a (Image)button. – P. Stephani May 13 '18 at 16:15
  • 1
    what is `fragmentTransaction.replace(R.id.tableLayout1, f1);` you should use `fragmentTransaction.replace(R.id.flContent, f1);` – Pavneet_Singh May 13 '18 at 16:16
  • 1
    Ah yes thanks alot!! it now replaces the first fragment! But the switch from the activity_main is still visible... Any ideas on how to replace it? – P. Stephani May 13 '18 at 16:27
  • @P.Stephani if you don't want the switch then either put it inside fragment layout or set the visibility to gone and you can accept the answer below if that worked for you – Pavneet_Singh May 13 '18 at 16:33
  • @Pavneet_Singh it's working inside fragment check this one `FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();` – Hardik Vasani May 14 '18 at 12:49

1 Answers1

2

To get fragmentManger in fragment use

getActivity().getSupportFragmentManager()

As mentioned You should use R.id.flContent as your frame layout host so use

fragmentTransaction.replace(R.id.flContent, f1);

instead of

fragmentTransaction.replace(R.id.tableLayout1, f1); 
Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68