Fragment Backstack
Solution 1:
Best way to achieve what you want is not to use fragment's backstack.
- Do not use
addToBackStack()
anywhere Keep your first fragment
LoginFragment
reference in the instance field mLoginFragment. Addition of your first fragment will look like this (probably in activity'sonCreate()
:FragmentTransactionfragmentTransaction= getFragmentManager().beginTransaction(); mLoginFragment = newLoginFragment(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit();
in your activity override
onBackPressed()
method as following:@OverridepublicvoidonBackPressed() { Fragmentfr= getFragmentManager().findFragmentById(R.id.authentication_parent0_linear); // chek that mLoginFragment!=null, basically this should never happen! if (fr == mLoginFragment) { super.onBackPressed(); } else { FragmentTransactionfragmentTransaction= getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit(); } }
There is a cumbersome way to achieve the desired effect with the use of backstack. Here is how:
- do not call
addToBAckStack()
when creating fragment A - When navigating from fragment A to B or to C, or to other fragments call
addToBackStack()
When navigating deeper from B to C, etc. call
popBackStack()
before the transaction. Explanation of it can be found on SO. Like this:getFragmentManager().popBackStack(); FragmentTransactionfragmentTransaction= getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, newFragmentC(), "whatever"); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit();
Solution 2:
The Fragment manager allows you to put a Name (or TAG) on a given state. If you pass that same name to popBackStack it will pop states until it reaches that state. For example
// Add initial fragment
getFragmentManager()
.beginTransaction();
.replace(R.id.authentication_parent0_linear, newLoginFragment());
.addToBackStack(TAG_FIRST_FRAGMENT_STATE) // The key is not passing null here
.commit();
// Add other fragments like such
getFragmentManager()
.beginTransaction();
.replace(R.id.authentication_parent0_linear, newSignupFragment());
.addToBackStack(null)
.commit();
// On back press@OverridepublicvoidonBackPressed() {
FragmentManagerfragmentManager= getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStack(TAG_FIRST_FRAGMENT_STATE, 0);
} else {
super.onBackPress();
}
}
Solution 3:
I fnally figured it out. based on Kirill K answer
publicclassMainActivityextendsActivityimplementsOnClickAuthentication,
LoginInterface, SignupInterface {
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
Fragmentfragment= fragmentManager.findFragmentByTag("one");
if (fragment == null) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, newOneFragment(), "one");
fragmentTransaction.commit();
}
}
@OverridepublicvoidonClickAuthButton(int flag) {
if (flag == 2) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, newTwoFragment(), "two");
fragmentTransaction.commit();
} else {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.relative, newThreeFragment(),
"three");
fragmentTransaction.commit();
}
}
@OverridepublicvoidswitchToSignup() {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, newThreeFragment(), "three");
fragmentTransaction.commit();
}
@OverridepublicvoidswitchToLogin() {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.relative, newTwoFragment(), "two");
fragmentTransaction.commit();
}
@OverridepublicvoidonBackPressed() {
FragmenttwoFragment= fragmentManager.findFragmentByTag("two");
FragmentthreeFragment= fragmentManager.findFragmentByTag("three");
if ((twoFragment != null && twoFragment.isVisible())
|| (threeFragment != null && threeFragment.isVisible())) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, newOneFragment(), "one");
fragmentTransaction.commit();
} else {
super.onBackPressed();
}
}
}
Solution 4:
I have done it like this
1. Globally declare fragmentManager variable :
FragmentManagerfm= getFragmentManager();
2.onCreate method load your 1st fragment without using backstack
fm.beginTransaction().replace(R.id.content_frame , new main_fragment()).commit();
3. now when you will add new fragment then create a method which will check if the fragment is already in backstack or not and also it will handle clicking the same fragment events(if you are using frag in navigation drawer )
voidreplaceFragment(Fragment fragment) {
Fragmentcurrent= fm.findFragmentById(R.id.content_frame);
//Check if that frag is already openedif (!current.getClass().equals(fragment.getClass())) {
StringbackStateName= fragment.getClass().getName();
booleanfragmentPopped= fm.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
//fragment is not in back stack,so add it.FragmentTransactionft= fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
else {
//if fragmentPopped is true then it will auto pop up the fragment//so we dnt have to do anything here
}
}
4. now just pass your fragment class to
replaceFragment(new yourfragment());
5. now handle backpress
publicvoidonBackPressed() {
int backStackEntryCount = fm.getBackStackEntryCount();
if (backStackEntryCount == 0) {
newAlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing Activity")
.setMessage("Are you sure you want to close this Application?")
.setPositiveButton("Yes", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
})
.setNegativeButton("No", null)
.setOnCancelListener(newDialogInterface.OnCancelListener() {
@OverridepublicvoidonCancel(DialogInterface dialogInterface) {
//backpress over alert dialogfinish();
System.exit(0);
}
})
.show();
} else {
super.onBackPressed();
}
}
Post a Comment for "Fragment Backstack"