57

I just started with fragment design for HoneyComb. I created two fragments. When i click a button in the left side fragment, a new fragment is created in right side. Meanwhile when i click a button in the right fragment(ie. DetialsFragment in my code below should be replaced by another fragment. main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
    <fragment class="com.fragment.example.Titles"
        android:id="@+id/titles" android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent" />
    <FrameLayout android:id="@+id/details" android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent" />

</LinearLayout>

FragmentExample.java

public class FragmentExample extends Activity {
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Titles.java

public class Titles extends Fragment {
    public FragmentTransaction ft;
    @Override
    public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.main1, null);
        Button button1 = (Button)v.findViewById(R.id.button1);
        button1.setText("santhosh");
        button1.setOnClickListener(new OnClickListener() {



            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                 DetailsFragment details = (DetailsFragment)
                            getFragmentManager().findFragmentById(R.id.details);
                    if (details == null || details.getShownIndex() != 1) {
                        // Make new fragment to show this selection.
                        details = DetailsFragment.newInstance(1);

                        // Execute a transaction, replacing any existing
                        // fragment with this one inside the frame.
                        ft
                                = getFragmentManager().beginTransaction();
                        ft.add(R.id.details, details, "detail");
                        ft.setTransition(
                                FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                        ft.commit();
                    }
            }

        });
        return v;
    }
}

DetailsFragment.java

public class DetailsFragment extends Fragment {
    /**
     * Create a new instance of DetailsFragment, initialized to
     * show the text at 'index'.
     */
    Titles title = new Titles();
    String[] titles = {"Title1", "Title2", "Title3", "Title4"};
    public static DetailsFragment newInstance(int index) {
        DetailsFragment f = new DetailsFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);

        return f;
    }

    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }

    @Override
    public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            // Currently in a layout without a container, so no
            // reason to create our view.
            return null;
        }
        Button button = new Button(getActivity());
        button.setText("Next");
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
            }
        });
        return button;
    }
}
Mohammedsalim Shivani
  • 1,793
  • 3
  • 19
  • 30
Santhosh_pulliman
  • 2,119
  • 6
  • 30
  • 47

7 Answers7

106

Then provided your button is showing and the click event is being fired you can call the following in your click event:

final FragmentTransaction ft = getFragmentManager().beginTransaction(); 
ft.replace(R.id.details, new NewFragmentToReplace(), "NewFragmentTag"); 
ft.commit(); 

and if you want to go back to the DetailsFragment on clicking back ensure you add the above transaction to the back stack, i.e.

ft.addToBackStack(null);

Or am I missing something? Alternatively some people suggest that your activity gets the click event for the button and it has responsibility for replacing the fragments in your details pane.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
PJL
  • 18,735
  • 17
  • 71
  • 68
  • 5
    Providing fragment tag is optional. You can do `ft.replace(R.id.details, new NewFragmentToReplace());` – Aniket Thakur Mar 15 '15 at 10:51
  • Also don't forget `getFragmentManager().executePendingTransactions();` – Aniket Thakur Mar 15 '15 at 11:05
  • 9
    The buttons doesn't go away of the previous fragment. The buttons of the old fragment are still visible on the top of the new fragment. – Santanu Nov 13 '16 at 06:39
  • 1
    @Santanu the reason it is happening is that the background color of the view is not set. Make it white and then it will work – Sambhav Khandelwal Apr 03 '22 at 10:37
  • @Santanu Check the R.id.details is the id of the parent fragment container, not of the current fragment. This fixed this issue for me. – Ben Jun 23 '22 at 10:12
  • @SambhavKhandelwal can you explain how this resolves the issue? I would need to change the toolbar shared by other activities to have a white background and would like to know the logic behind this fix – Gil Ong May 15 '23 at 09:20
6

Latest Stuff

Okay. So this is a very old question and has great answers from that time. But a lot has changed since then.

Now, in 2020, if you are working with Kotlin and want to change the fragment then you can do the following.

  1. Add Kotlin extension for Fragments to your project.

In your app level build.gradle file add the following,

dependencies {
    def fragment_version = "1.2.5"

    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
    // Testing Fragments in Isolation
    debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
}
  1. Then simple code to replace the fragment,

In your activity

supportFragmentManager.commit {
    replace(R.id.frame_layout, YourFragment.newInstance(), "Your_TAG")
    addToBackStack(null)
}

References

Check latest version of Fragment extension

More on Fragments

gprathour
  • 14,813
  • 5
  • 66
  • 90
  • 1
    This works for Kotlin as of today, just replace the version with current version from here `https://developer.android.com/jetpack/androidx/releases/fragment` – Neo Wakeup Apr 12 '21 at 12:07
2

You can try below code. it’s very easy method for push new fragment from old fragment.

private int mContainerId;
private FragmentTransaction fragmentTransaction;
private FragmentManager fragmentManager;
private final static String TAG = "DashBoardActivity";

public void replaceFragment(Fragment fragment, String TAG) {

    try {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(mContainerId, fragment, tag);
        fragmentTransaction.addToBackStack(tag);
        fragmentTransaction.commitAllowingStateLoss();

    } catch (Exception e) {
        // TODO: handle exception
    }

}
Jahid
  • 21,542
  • 10
  • 90
  • 108
Jignesh Goyani
  • 1,020
  • 9
  • 17
2

Use android.support.v4.app for FragmentManager & FragmentTransaction in your code, it has worked for me.

DetailsFragment detailsFragment = new DetailsFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.details,detailsFragment);
fragmentTransaction.commit();
Madhu Jayarama
  • 415
  • 1
  • 5
  • 15
2

If you have a handle to an existing fragment you can just replace it with the fragment's ID.

Example in Kotlin:

fun aTestFuction() {
   val existingFragment = MyExistingFragment() //Get it from somewhere, this is a dirty example
   val newFragment = MyNewFragment()
   replaceFragment(existingFragment, newFragment, "myTag")
}

fun replaceFragment(existing: Fragment, new: Fragment, tag: String? = null) {
    supportFragmentManager.beginTransaction().replace(existing.id, new, tag).commit()
}
James Jones
  • 1,486
  • 1
  • 12
  • 22
1

Updated Answer (Working for Overlap problem as well)

@aniket-thakur(https://stackoverflow.com/users/2396539/aniket-thakur) gave correct answer. Thank you for that!

But, getFragmentManager() is deprecated, so following code did work for me.

final FragmentTransaction ft = getParentFragmentManager().beginTransaction();
                ft.replace(R.id.nav_host_fragment, new GalleryFragment(), "NewFragmentTag");
                ft.addToBackStack(null);
                ft.commit();
Amit Kadam
  • 589
  • 6
  • 7
0

it's very simple how to replace with Fragment.

DataFromDb changeActivity = new DataFromDb();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.changeFrg, changeActivity);
    transaction.commit();
Supriyanto
  • 149
  • 2
  • 10