Here's how I do it,
- create an interface that would receive
onBackPressed()
in any class
that implements it and would return true if it's handling the method or false otherwise. This would make sure that your app would exit when your return false.
- create a stack of these interfaces in your
Activity
, then add any of such interfaces to it.
- override
onBackPressed()
in your activity, then anytime it's called, get a listener from the stack and call its own onBackPressed()
if it returns true. If it returns false, then it's not handling onBackPressed()
so Activity can take over and remove fragment or exit the application.
Here's a sample implementation.
In your Activity
public class MyActivity extends Activity {
//a stack of OnBackPressedListeners, stack one when you want it to receive onBackPressed() from
//this activity.
//PS used stack so that by LIFO, the last listener would be the first to be called.
private Stack<OnBackPressedListener> onBackPressedListeners = new Stack<>();
@Override
public void onBackPressed() {
if (!onBackPressedListeners.isEmpty()) {
if (onBackPressedListeners.peek().onBackPressed()) //if interface is handling onBackPressed(), return. Otherwise super would be called below.
return;
}
//if no listeners, then do super. This would ensure natural behaviour such as closing the app or popping a fragment when no listeners are using onBackPressed()
super.onBackPressed();
}
//listener interface
public static interface OnBackPressedListener {
/**
* @return true if you're handling onBackPressed, false otherwise to let super.onBackPressed() take over
*/
public boolean onBackPressed();
}
public void addOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.add(listener);
}
public void removeOnBackPressedListener(OnBackPressedListener listener) {
onBackPressedListeners.remove(listener);
}
}
In your Fragment
//implement OnBackPressedListener in your fragment.
public class MyFragment extends Fragment implements OnBackPressedListener {
//find somewhere to add the listener to your Activity, most likely in onCreateView(...)
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
((MyActivity)getActivity()).addOnBackPressedListener(this);
...
return view;
}
//overide onBackPressed(), then return true if you're handling the onBackPressed(), false otherwise.
@Override
public boolean onBackPressed() {
if (slider_call_phones.isOpened()) {
slider_call_phones.closeLayer(true);
return true;
}
return false;
}
//lastly remember to remove the listener when your fragment is destroyed, so that it stops receiving callbacks,
//if you don't do this, you might get a NullPointerException.
@Override
public void onDestroy() {
super.onDestroy();
((MyActivity)getActivity()).removeOnBackPressedListener(this);
}
}
I mostly use a single Activity
and a whole lot of Fragment
's in my Android apps, this is exactly how I solve such problems you are having, for example closing a drawer in a Fragment if its open when the back button is pressed, or exiting the application if it's closed.