Creating separate back stacks for Android application tabs

Creating separate back stacks for Android application tabs

The Problem Outline

Suppose we have a simple Android application with several tabs. The standard approach uses Fragments and ActionBar to organize tabs and manage navigation. This setup works well when each tab has only one screen.

However, issues arise when the app needs to support navigation between different tabs and multiple screens within a single tab. Problems occur specifically when you need to handle “horizontal” navigation between tabs and “vertical” navigation within tabs that have several screen fragments.

The main issue is with the Back button behavior. The regular implementation of the Back button can lead to problems like mixing content from different tabs, showing a black empty screen, or displaying incorrect content. For example, content from another tab might appear unexpectedly.

This issue arises because the back stack, which is a stack of all activities and fragments in the order they were opened, is shared across all tabs. The back stack is not rearranged for each tab. Therefore, the Back button does not remember the order in which you visited screens across different tabs. It simply pops the last item added to the back stack each time it is clicked.

Here are some examples of the Back button messing up the app screen:

Separate-Back-Stacks-Back-Button-2В  В Separate-Back-Stacks-Back-Button-1

Solution: use a hashmap to manage separate back stacks for fragments in different tabs.

To be able to solve the navigation problem we will implement separate back stack for each tab. Specifically, we’ll maintain custom stacks by saving navigation history as a map of tab tags and screen fragments which belong to them. In addition to that we’ll have to implement some methods for managing fragments using this map.

Implementation example and some code explanations

To illustrate the usage of tabs and fragments mapping in practice we’ve prepared a little sample project. You can download all the source files using the links at the end of this article and inspect them closely, but we’ll explain some code in the article as well. Note that Support Library and ActionBarSherlock were used in the solution to provide code compatibility for devices that run Android 2.2 and newer.

MainActivity.java methods:

1. Creating tabs

The tabs are created in OnCreate methods in the host activity which extends FragmentActivity:


@Override
 protected void onCreate(Bundle savedInstanceState) {...}

2. Adding variables for keeping screen fragments and tabs tags

// Tabs associated with list of fragments
private Map<String, List<Fragment>> fragmentsStack = new HashMap<String, List<Fragment>>();
private String currentSelectedTabTag = "";
3. Adding methods for managing screen fragments


/**
 * Method is used to show the next fragment from current one
 * @param nextFragment The fragment object which will be shown
 */
 public void showFragment(Fragment nextFragment) {...}
/**
 * Method for adding list of fragments for tab to our Back Stack
 * @param tabTag The identifier tag for the tab
 */
 public void createStackForTab(String tabTag) {...}

/**
 * @param fragment The fragment that will be added to the Back Stack
 */
 public void addFragmentToStack(Fragment fragment) {...}

/**
 * Used in TabListener for showing last opened screen from selected tab
 * @return The last added fragment of actual tab will be returned
 */
 public Fragment getLastFragment() {...}

/**
 * Override default behavior of hardware Back button
 * for navigation through fragments on tab hierarchy
 */
 @Override
 public void onBackPressed() {...}

Using ActionBarSherlock in TabListener.java methods:


/** Constructor used each time a new tab is created.
 * @param activity The host Activity, used to manage the fragments
 * @param tag The identifier tag for the tab
 * @param clz The fragment's Class, used to instantiate the first fragment of tab
 */
public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {...}

public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {...}

Results

Now the Back button should work as intended and remove the last fragment of the respective tab from this tab custom back stack, and not the last fragment that has been added to the common back stack. Keep in mind that if you choose to use this approach, you’ll have to handle switching between portrait and landscape orientations (or you just can disable screen rotation in the AndroidManifest.xml).

Download the project files here: Separate Back Stacks for Android Fragments Tabs.zip

Helpful links

Using Fragments

Using ActionBar

Support Library

ActionBarSherlock

Regular implementation

Summary
Creating Separate Back Stacks for Android Applications - Abto Software
Article Name
Creating Separate Back Stacks for Android Applications - Abto Software
Description
How to improve in-app navigation by creating separate back stacks for each tab when developing Android apps using Fragments and ActionBar.
Publisher Name
Abto Software
Publisher Logo

Mobile App Development

Writing software accessible anytime everywhere

Contact us

Tell your idea, request a quote or ask us a question