120

I have try to close the current fragment by using Imagebutton.

I am in Fragment-A and it will turn to the Fragment-B when I click the button.

And when I click the button at Fragment-B , it will turn to the Fragment-C and close the Fragment-B.

If I click the back button at Fragment-C , it will back to the Fragment-A.

The code I have try is like the following

camera_album = (ImageButton) view.findViewById(R.id.camera_album);

camera_album.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {

                    closefragment();
        Fragment fragment = FileBrowserFragment.newInstance(null, null, null) ;
        MainActivity.addFragment(LocalFileBrowserFragment.this, fragment) ;


    }
});

private void closefragment() {
    getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}

When I click the back button at fragment-B , it turn to the Fragment-C.

But when I click the back button on Fragment-C , it doesn't back to the Fragment-A. It back to the empty background. If I want to back to Fragment-A , I have to click the back button once again.

SO , it seem doesn't close the current fragment complete.

How to finish the current fragment like the back button of Android ?

Morteza Jalambadani
  • 2,190
  • 6
  • 21
  • 35
Wun
  • 6,211
  • 11
  • 56
  • 101

14 Answers14

176

I changed the code from

getActivity().getFragmentManager().beginTransaction().remove(this).commit();

to

getActivity().getFragmentManager().popBackStack();

And it pops out the top fragment

SilleBille
  • 605
  • 5
  • 21
Wun
  • 6,211
  • 11
  • 56
  • 101
  • This worked for me context.supportFragmentManager.beginTransaction().remove(this@MyFragment).commit() – Faizan Haidar Khan Nov 05 '21 at 17:20
  • With fragment of type androidx.fragment.app.Fragment, this seems to leave the fragment header. Therefore I have my main app, with the popped fragment header still showing. The getActivity().onBackPressed() seem to work better for me. – Ben Jun 22 '22 at 15:08
  • 3
    Don't forget to use "getSupportFragmentManager()" in case "getFragmentManager()" isn't working for you – Joe Okatch Sep 12 '22 at 13:49
  • Unfortunately this is outdated. Use: OnBackPressedCallback from now on. – Dominik Oct 01 '22 at 14:26
88

For those who need to figure out simple way

Try getActivity().onBackPressed();

Viswanath Lekshmanan
  • 9,945
  • 1
  • 40
  • 64
  • getActivity() can be null lot of times. – Arpit J. Dec 17 '19 at 07:44
  • 2
    @ArpitJ. it's only null before onAttach() is called, a fragment can't live without an activity. – Tamim Attafi Jan 30 '20 at 11:05
  • @TamimAttafi True, but I was referring to cases like rotation or activity is finished and due to some reason fragment instance is still there then it will return null. – Arpit J. Jan 30 '20 at 11:19
  • 4
    `popBackStack()` and `popBackStackImmediate()` are more direct ways of popping the topmost fragment without simulating a button press. Using `onBackPressed()` triggers `OnBackPressedCallback`s; if in the future you want to handle Back button presses specifically, you'll have to switch to `popBackStack()`/`popBackStackImmediate()` to avoid triggering the callbacks programmatically. – Nolan Amy Aug 22 '20 at 18:08
  • You put this code inside the Fragment's buttons's onclick method. – Anon Oct 13 '20 at 13:24
  • Terrible solution. Altho it gives the results initially, it can cause many problems once you start overriding OnBackPress or if let's say the keyboard is open or something, the back press you initiate will only close the keyboard not the fragment. And these are only a few of the many possible problems you can encounter with this solution. User popBackStack() or popBackStackImmediate(). – Itay Feldman May 18 '21 at 11:24
87

From Fragment A, to go to B, replace A with B and use addToBackstack() before commit().

Now From Fragment B, to go to C, first use popBackStackImmediate(), this will bring back A. Now replace A with C, just like the first transaction.

S.D.
  • 29,290
  • 3
  • 79
  • 130
  • 4
    for usinf popStackImmediate() :-> getView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { getActivity().getSupportFragmentManager().popBackStackImmediate() ; return true; } return false; } }); – Yash Agrawal Sep 25 '16 at 05:18
6

Try this:

public void removeFragment(Fragment fragment){
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.remove(fragment);
    fragmentTransaction.commit();
}
Gowthaman M
  • 8,057
  • 8
  • 35
  • 54
5

This is a Kotlin way of doing this, I have created button in fragment layout and then set onClickListner in onViewCreated.

according to @Viswanath-Lekshmanan comment

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) 
{
     super.onViewCreated(view, savedInstanceState)

     btn_FragSP_back.setOnClickListener {
        activity?.onBackPressed()
    }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Abdul Rehman
  • 2,224
  • 25
  • 30
5

You can try this logic because it is worked for me.

frag_profile profile_fragment = new frag_profile();

boolean flag = false;
@SuppressLint("ResourceType")
public void profile_Frag(){
    if (flag == false) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.setCustomAnimations(R.anim.transition_anim0, R.anim.transition_anim1);
        transaction.replace(R.id.parentPanel, profile_fragment, "FirstFragment");
        transaction.commit();
        flag = true;
    }

}

@Override
public void onBackPressed() {
    if (flag == true) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.remove(profile_fragment);
        transaction.commit();
        flag = false;
    }
    else super.onBackPressed();
}
Rahul Rathore
  • 658
  • 8
  • 6
4

Try this:

ft.addToBackStack(null);   // ft is FragmentTransaction

So, when you press back-key, the current activity (which holds multiple fragments) will load previous fragment rather than finishing itself.

Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
4
Button ok= view.findViewById(R.id.btSettingOK);
Fragment me=this;
ok.setOnClickListener( new View.OnClickListener(){
    public void onClick(View v){
     getActivity().getFragmentManager().beginTransaction().remove(me).commit();
    }
});
Manu
  • 4,730
  • 2
  • 20
  • 45
Bruno L.
  • 457
  • 6
  • 8
  • 3
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – rollstuhlfahrer Mar 03 '18 at 14:25
  • 1
    This simple code actually removes the current fragment view by a OK or Close button on it. I use it for quitting a light setting panel displayed as a Fragment and go back to the Activity. Sorry for this trick but under Android 8, I think it is not so practical to manage multiple Fragment. – Bruno L. Mar 04 '18 at 03:26
0

If you need to handle the action more specifically with the back button you can use the following method:

view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if( keyCode == KeyEvent.KEYCODE_BACK )
        {
            onCloseFragment();
            return true;
        } else {
            return false;
        }
    }
});
Morteza Jalambadani
  • 2,190
  • 6
  • 21
  • 35
0

In your Fragments onCreateView(...) you can remove a view by calling container.removeView(view);. So if you want to remove the fragment, then view should be the return value of onCreateView,

for example

    public View onCreateView(...){
        final View view = inflater.inflate(R.layout.your_fragments_layout,container,false);
        //Do something
        finishButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                container.removeView(view);
            }
        });
        return view;
    }
Ilmard
  • 86
  • 4
0

For remove current fragment B and navigate to stack back (other fragment A):

private fun navigateToBackStack() {
    requireActivity().supportFragmentManager
        .beginTransaction()
        .remove(this)
        .commit()
    requireActivity().supportFragmentManager.popBackStack()
}

GL

Braian Coronel
  • 22,105
  • 4
  • 57
  • 62
0

If you use JetPack Navigation, write:

findNavController().popBackStack()
CoolMind
  • 26,736
  • 15
  • 188
  • 224
0

For those using DialogFragment, just call .dismiss().

OzgurG
  • 1,634
  • 1
  • 16
  • 21
-13

Try this one

getActivity().finish();
Karan Chunara
  • 518
  • 4
  • 15
  • 1
    Try explaining your answer more , so that its easy for OP and other people to understand the answer who come back to this question in future – Aman Chhabra Jul 09 '18 at 14:18
  • 7
    this closes the whole activity, not the fragment – busuu Aug 18 '18 at 20:01
  • It helped me. Those who want more information may google it. No need to copypaste here official documentation. – Alesha170 Jul 13 '19 at 14:08
  • If you are using BottomNavigationView which usually has one activity, this command will close the app instead of getting back to the previous fragment. – Aliton Oliveira Nov 29 '19 at 16:05