Android Fragment Handle Back Button Press

Android Fragment handle back button press

When you are transitioning between Fragments, call addToBackStack() as part of your FragmentTransaction:

FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag" ).commit();

If you require more detailed control (i.e. when some Fragments are visible, you want to suppress the back key) you can set an OnKeyListener on the parent view of your fragment:

//You need to add the following line for this solution to work; thanks skayred
fragment.getView().setFocusableInTouchMode(true);
fragment.getView().requestFocus();
fragment.getView().setOnKeyListener( new OnKeyListener()
{
@Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return false;
}
} );

How to detect when back button pressed in fragment android?

In your MainActivity

@Override
public void onBackPressed()
{
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView,new Recommendation()).commit();
}

Handle back pressed on fragment then continue navigating

You're overriding the usual back-pressed behaviour, which is why it doesn't navigate back. You need to call parentFragmentManager.popBackStack() (or findNavController().popBackStack() if you're using the Navigation component).

Your other option is to do setEnabled = false in the callback after you remove your podcast (meaning the handler won't be called next time) and then immediately fire a back-pressed event with activity?.onBackPressed(). That will handle it with the default behaviour (unless you've added more dispatchers! In which case it'll fall through to the next one)


edit: I've used the popBackStack stuff myself, but it might be a better idea to use the "disable dispatcher and re-fire" approach in general. Purely because the standard behaviour could possibly change (a lot is going on with back stacks and navigation development) so hardcoding a popBackStack call might lead to problems down the line.

I don't know what the official line is though - the docs have this to say:

Changing the enabled state on the OnBackPressedCallback is strongly recommended for temporary changes as it maintains the ordering described above, which is particularly important if you have callbacks registered on multiple different nested lifecycle owners.

but that's more about changing the response to a back press temporarily, not handling one press and messing around, firing multiple events to generate a particular standard behaviour

How to handle Back Button press in android fragments

I think you can do this:

Create a generic Fragment:

public abstract class extends BaseFragment {

public abstract boolean onBackPressed();

}

In his Fragments, extends this BaseFragment, example:

public class TopStoriesFragment extends BaseFragment {

...


@Override
public boolean onBackPressed()
{
//if you return false, then it is because you have not consumed
//the event, but if it returns true, which is consumed by this event.
return false;
}
}

In his MainActivity activity, you should check in onBackPressed event, if the event was consumed or not, to decide what to do.

It is very important that you save the current tab!

public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {

//It is very important that you save the current tab!
private BaseFragment currentTab;

// ... implementation



public class TabsPagerAdapter extends FragmentPagerAdapter {

public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int index) {

currentTab = null;

switch (index) {
case 0:
// Top Rated fragment activity
currentTab = new TopStoriesFragment();
break;
case 1:
// Games fragment activity
return new NationalFragment();
case 2:
// Movies fragment activity
currentTab = new InternationalFragment();
break;
case 3:
// Movies fragment activity
currentTab = new SportsFragment();
break;
case 4:
// Movies fragment activity
currentTab = new TechnologyFragment();
case 5:
// Movies fragment activity
currentTab = new BusinessFragment();
break;
case 6:
// Movies fragment activity
currentTab = new EntertainmentFragment();
break;
}


return currentTab;
}

@Override
public int getCount() {
// get item count - equal to number of tabs
return 7;
}

public void stop() {
// get item count - equal to number of tabs
return;
}

}


@Override
public void onBackPressed()
{
//If the event returned false, then call the super.
if(currentTab == null || !currentTab.onBackPressed())
super.onBackPressed();
}

}

Change to your case!

Handling back button in Android Navigation Component

Newest Update - April 25th, 2019

New release androidx.activity ver. 1.0.0-alpha07 brings some changes

More explanations in android official guide: Provide custom back navigation

Example:

public class MyFragment extends Fragment {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// This callback will only be called when MyFragment is at least Started.
OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
@Override
public void handleOnBackPressed() {
// Handle the back button event
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

// The callback can be enabled or disabled here or in handleOnBackPressed()
}
...
}

Old Updates

UPD: April 3rd, 2019

Now its simplified. More info here

Example:

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), this);

@Override
public boolean handleOnBackPressed() {
//Do your job here
//use next line if you just need navigate up
//NavHostFragment.findNavController(this).navigateUp();
//Log.e(getClass().getSimpleName(), "handleOnBackPressed");
return true;
}

Deprecated (since Version 1.0.0-alpha06
April 3rd, 2019) :

Since this, it can be implemented just using JetPack implementation OnBackPressedCallback in your fragment
and add it to activity:
getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);

Your fragment should looks like this:

public MyFragment extends Fragment implements OnBackPressedCallback {

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);
}

@Override
public boolean handleOnBackPressed() {
//Do your job here
//use next line if you just need navigate up
//NavHostFragment.findNavController(this).navigateUp();
//Log.e(getClass().getSimpleName(), "handleOnBackPressed");
return true;
}

@Override
public void onDestroyView() {
super.onDestroyView();
getActivity().removeOnBackPressedCallback(this);
}
}

UPD:
Your activity should extends AppCompatActivityor FragmentActivity and in Gradle file:

 implementation 'androidx.appcompat:appcompat:{lastVersion}'

Fragment pressing back button

In your onCreate() in your activity housing your fragments add a backstack change listener like so:

    fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});

(Nb. my fragmentManager is declared global)
Now every time you change fragment the currentFragment String will become the name of the current fragment. Then in the activities onBackPressed() you can control the actions of your back button as so:

    @Override
public void onBackPressed() {

switch (currentFragment) {
case "FragmentOne":
// your code here
return;
case "FragmentTwo":
// your code here
return;
default:
fragmentManager.popBackStack();
// default action for any other fragment (return to previous)
}

}

I can confirm that this method works for me.

Update : Kotlin

override fun onBackPressed() {

when(supportFragmentManager.fragments[0].javaClass.simpleName){
"FragmentOne" -> doActionOne()
"FragmentTwo" -> doActionTwo()
else -> supportFragmentManager.popBackStack()
}
}


Related Topics



Leave a reply



Submit