I have two fragments FirstFragment and WelcomeFragment ,
in FirstFragment i have some animation and i load data from server then i navigate to WelcomeFragment using NavController :
navController.navigate(R.id.action_firstFragment_to_welcomeFragment);
and my nav_graph is like this :
<fragment
android:id="@+id/firstFragment"
android:name="com.flyeducation.UI.FirstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_firstFragment_to_welcomeFragment"
app:destination="@id/welcomeFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in"
app:popExitAnim="@anim/fade_out" />
</fragment>
i want ot have this behaviour :
navigating from FirstFragment to WelcomeFragment but not having the ability to go back to FirstFragment when pressing the back button the app should close like pressing the home Button and when coming back staying in the WelcomeFragment
from the documentation i tried in the nav_graph XML :
app:popUpTo="@id/firstFragment"
app:popUpToInclusive="true"
the app closes but when i go back to it , it does start all over again from the FirstFragment and not maintaining the state that i want which is staying in WelcomeFragment
from other questions i also tried this in WelcomeFragment :
navController.popBackStack(R.id.firstFragment, true);
Anyone can help me achieving the wanted behaviour
EDIT :
I ended up intercepting the onKeyDown and also Simulating Home click when it onKeyDown is pressed on my WelcomeFragment
This in my WelcomeFragment
public void myOnKeyDown(int key_code, Context context){
openDialog(context);
}
public void openDialog(final Context context) {
new AlertDialog.Builder(context)
.setTitle("Exit ! ")
.setMessage("Are you sure you wanna quit our App , we will miss you !")
.setNegativeButton(android.R.string.cancel, null) // dismisses by default
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
context.startActivity(i);
}
})
.create()
.show();
}
and this in my Activity :
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
((WelcomeFragment) WelcomeFragment).myOnKeyDown(keyCode, this);
return false ;
}
This has give me the behaviour i want but i do not think it is best practice
So this is the right solution to be used in my case , it will have the same behaviour described in the question and like what i had when overriding onKeyDown
in MainActivity
OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
@Override
public void handleOnBackPressed() {
openDialog(getContext());
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), callback);
Another clue :
app:popUpTo="@id/fragment"
is used when the fragment is in the back stack
and
app:popUpToInclusive="true"
will clear the stack untill hitting the fragment id in app:popUpTo
described here popUpTo and popUpToInclusive