0

Imagine one activity with 3 fragments: starts showing the first one, select a menu option and go to the second one, select another option and go to the 3rd fragment and select again the first option an return to the second one.

f1 -> f2 -> f3 -> f2

When I press back I want the app returns to fragment 3 and when I press back again it should return to fragment 1 and if press back again, close the app. Something like if the fragment exists, move it to top of the stack and if not, create it.

Thank you!

3
  • use urFragment.addToBackStack(null); to add to backstack Commented Oct 19, 2015 at 5:47
  • yes but if I select the same option twice it adds twice to de stack... Commented Oct 19, 2015 at 5:49
  • show some code where you have tried to do this Commented Oct 19, 2015 at 5:51

2 Answers 2

1

Here is solution I came up over time. The idea is following, you need to keep a stack data structure and whenever you add a fragment add it to stack as well, then override onBackPress method and check if stack is not empty then replace your fragment container with new fragment from top of the stack when it is empty do super.onbackpress So here is a parent class for all kind of fragment based navigation.

public abstract class FragmentsStackActivity extends BaseActivity { public static final String TAG_BUNDLE = "bundle_tag"; protected final Bundle fragmentArgs = new Bundle(); protected Stack<Fragment> fragments = new Stack<>(); abstract protected void setupFragments(); public void setFragmentArguments(Fragment fragment, Bundle arguments){ if(!fragments.isEmpty() && fragments.peek()!=fragment){ fragment.setArguments(arguments); } } public void setFragmentFromStack() { if(!fragments.isEmpty()) { Fragment fragment = fragments.peek(); final Fragment oldFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); if (oldFragment == null || oldFragment != fragment) { getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); //transaction.setCustomAnimations(R.anim.animator_left_right_in, R.anim.animator_left_right_in); transaction.replace(R.id.fragment_container, fragment).commit(); } }else { finish(); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //TODO need to save fragment stack } } 

example of an activity that extends this class

public class LoginActivity extends FragmentsStackActivity{ private final MyFragment1 fragment1 = new MyFragment1(); private final MyFragment2 fragment2 = new MyFragment2(); private final User mUser = new User(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); setupFragments(); setFragmentFromStack(); } @Override protected void setupFragments() { fragments.add(fragment2); //fragment2.setNotifier(this); // I use notifiers listener but you can choose whatever convenient for you Bundle fragmentArgs = new Bundle(); fragmentArgs.putBoolean(Constants.TAG_LOGIN, true); fragmentArgs.putParcelable(User.TAG, mUser); fragmentArgs.putInt(Constants.TYPE, getIntent().getIntExtra(Constants.TYPE, 0)); fragment2.setArguments(fragmentArgs); //fragment1.setNotifier(this); // I use notifiers listener but you can choose whatever convenient for you } // this method teals with handling messages from fragments in order to provide navigation // when some actions taken inside the fragment, you can implement your own version public void onReceiveMessage(String tag, Bundle bundle) { switch (tag) { case MyFragment2.TAG_BACK: case MyFragment1.TAG_BACK: fragments.pop(); setFragmentFromStack(); break; case MyFragment2.TAG_NEXT: fragment1.setArguments(bundle); fragments.add(fragment1); setFragmentFromStack(); break; case MyFragment1.TAG_NEXT: goToWelcomeScreen(bundle); finish(); break; } } private void goToWelcomeScreen(Bundle bundle){ } } 
Sign up to request clarification or add additional context in comments.

Comments

0

You can implement this with the help of the following code:

// transaction.replace(R.id.detailFragment, frag1); Transaction.remove(null).add(frag1) // frag1 on view // transaction.replace(R.id.detailFragment, frag2).addToBackStack(null); Transaction.remove(frag1).add(frag2).addToBackStack(null) // frag2 on view // transaction.replace(R.id.detailFragment, frag3); Transaction.remove(frag2).add(frag3) // frag3 on view 

And for better understanding, have a ook at the following snippet:

// Works with either the framework FragmentManager or the // support package FragmentManager (getSupportFragmentManager). getSupportFragmentManager().beginTransaction() .add(detailFragment, "detail") // Add this transaction to the back stack .addToBackStack() .commit(); getSupportFragmentManager().addOnBackStackChangedListener( new FragmentManager.OnBackStackChangedListener() { public void onBackStackChanged() { // Update your UI here. } }); 

have a look here http://developer.android.com/training/implementing-navigation/temporal.html

5 Comments

why are you removing fragment 1 to add fragment 2?
that way, when you press back button you won't go to fragment 1...because it's been replaced by fragment 2...so you can do stuff related to that to accomplish your requirement
I want to return to fragment 1, I only want to avoid the same fragment twice in the stack...
You'll have to replace your frag 2 when adding a new frag 2 in that way you'll not have two frag 2.
it seems there's a lot of confusion here , just get your work done ... here is the link , just the problem you are facing stackoverflow.com/questions/27957789/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.