To support more dynamic and flexible UI design on large screens such as tablets, Android introduced Fragments in 3.0 (API Level 11). With the widespread use of Fragments, it is not easy to manage the task stack when its usage scenarios are inconsistent with the default behavior of the Android framework (medium.com/square-corn… Tubi had some problems with task stack management using Fragments, so we created an open source project called FragmentOperator (github.com/Tubitv/Frag… Kotlin code demonstrates how to use the FragmentOperator to make it easier for Android developers to manage the Fragment return stack.

from“Tag” * * * *Speaking of

Google recommends FragmentTransaction for fragment-related operations, which are added to the return stack so that we can do the reverse. To better implement custom unstack operations, we need to identify and group some fragments so that we can customize their order. By adding tags, we can achieve this goal easily and efficiently.

The above code with the official Google developer documentation FragmentTransaction usage (developer.android.com/guide/compo…

  • Add FragmentTag to the Fragment instance so that we can retrieve it if needed using findFragmentByTag:

    fragmentTransaction.replace(containerId, fragment, fragmentTag)

  • Transactions are also marked when they are added to the back stack to facilitate the use of popBackStack to push transactions off the stack:

    fragmentTransaction.addToBackStack(fragmentTag)

In the FragmentOperator codebase, we use the same tag for both fragment and transaction for ease of lookup and reference. Each Fragment instance corresponds to a unique tag, allowing you to manage multiple instances of the same fragment class. And save and manage every fragment tag in the code.

The code above is part of the BaseFragment parent class of all Fragments in the project. Since the Fragment instance can be recreated after the Activity configuration is changed (such as the orientation of the phone), and the old fragment hashcode is different from the old one, we create the fragmentTag only once and store it in the bundle. Use getFragmentTag() to get each fragment tag corresponding to a transaction.

The stack automatically skips f__ragment

The following examples illustrate the applicable scenarios of FragmentOperator:

If we are developing an e-commerce application that supports tourist mode, after the user installs the App, he/she enters the home Page (HomeFragment) to browse the thumbnail of a commodity without logging in. After clicking a commodity, an AuthFragment page will be displayed for the user to log in or register. After successful login, the DetailFragment page is displayed, and the fragment task stack looks like this:

When the user hits the back button on the DetailFragmemt page, by default the Android FragmentManager popBackStack() method is called to display the previous page, the AuthFragment page, This is clearly not what users want. Now that the user is logged in, we want the application to skip the AuthFragment page and display the HomeFragment smoothly.

One way to achieve this effect is to call popBackStack() twice, but visually there is a switch in the middle of the page. Now the requirement is only need to skip a page (AuthFragment), if the need to skip multiple pages how to deal with the situation? We certainly don’t want to call the popBackStack() method multiple times, but it would be nice if it could be handled automatically.

Android FragmentManager gives developers a way to skip certain fragments when they leave the stack:

popBackStack(String name, int flags)

If you mark an AuthFragment as a skippable Fragment instance and keep the tag of the previous HomeFragment instance, you can skip the AuthFragment stored in the fragment return stack. Return to HomeFragment. The key is to save and maintain the correct tags for the Fragment instance.

In FragmentOperator, a variable we maintain in BaseFragment previousFragmentTag represents the fragment that should be displayed after the current fragment is removed from the stack. Another variable, skipOnPop, represents whether the current fragment is skipped when it returns to the stack.

When loading a new fragment instance, the current fragment skipOnPop value determines the new fragment previousFragmentTag value. PreviousFragmentTag Indicates the fragment tag to be displayed when a new fragment is removed from the return stack.

When popBackStack is called, using the current Fragment previousFragmentTag value, you can retrieve the fragment displayed when returned. This makes it easy to customize the fragment order and skip unnecessary pages.

In some cases, we want only one instance of the same fragment to appear in the Fragment task stack. Going back to the example, it is quite possible that the AuthFragment page is not just one page, but two pages, such as the SignInFragment page and the SignUpFragment page. The login page has a button to jump to the SignUpFragment page, and vice versa.

If the user opens the login page on the registration page and clicks the registration button on that page to reopen the registration page, if nothing special is done, another instance of the registration page will be created and added to the task stack, which now looks like this:

In some cases, it is possible for the user to keep clicking on the Login and registration buttons, so that clicking on the back button will result in a deeply nested navigation view. In this case, the developer should display the previous login or registration page, rather than constantly creating new pages to load onto the task stack. In this case, the FragmentOperator flags fragments that want to hold only one instance in the task stack:

@SingleInstanceFragment

public class SignUpFragment {}

When loading a new fragment, the FragmentOperator checks to see if the @SingleInstanceFragment tag has been added to the fragment class. If so, The fragment instance is returned to the previous fragment by pushing it out of the stack, and a new instance is created and added to the return stack. This effectively handles the update of the fragment content.

Now, developers just need to add @SingleInstanceFragment to the corresponding fragment, and the FragmentOperator library will automatically handle cases where there is only one instance in the return stack.

FragmentOperator

The fragment-related features described above have been collated and incorporated into Tubi’s open source FragmentOperator project to make it easier for you to use fragments. Developers are welcome to try it, and we sincerely hope to get more valuable feedback.

This post is from the Tubi Android Team

Everyone can watch high-quality content for free

Click follow to learn more