Skip to content

2. Basic Usage

Gabor Varadi edited this page Jun 1, 2020 · 6 revisions

How to change the navigation history?

For most cases, Backstack provides:

  • goTo(): add to backstack, or go back to it if already exists
  • goBack(): go back if no state change is currently in progress. Returns false if can't go back (in progress or only 1 key).
  • setHistory(): sets the navigation history, with a given direction.

There are also secondary operators, namely:

  • jumpToRoot()
  • goUp()
  • goUpChain()
  • replaceTop()
  • moveToFront()

If you use Navigator (which you probably do), then you can obtain a reference to the Backstack using Navigator.getBackstack(context).

Handling state changes

The simple case

In the case of synchronous state changes, the StateChanger can be a SimpleStateChanger, that receives a NavigationHandler.

class MainActivity : AppCompatActivity(), SimpleStateChanger.NavigationHandler {
    private lateinit var fragmentStateChanger: FragmentStateChanger

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fragmentStateChanger = FragmentStateChanger(supportFragmentManager, R.id.root)

        Navigator.configure()
            .setStateChanger(SimpleStateChanger(this))
            .install(this, root, History.of(FirstScreen()))
    }

    override fun onBackPressed() {
        if (!Navigator.onBackPressed(this)) {
            super.onBackPressed()
        }
    }

    override fun onNavigationEvent(stateChange: StateChange) {
        fragmentStateChanger.handleStateChange(stateChange)
    }
}

How it works

When the state stored by the backstack is modified (meaning when you navigated from some view to another), the StateChanger is called to let you handle this state change. The state change contains the previous keys, and the new keys.

When the state change is completed, the completion callback must be called. This callback enables asynchronous state changes as well. As long as a state change is in progress, other state changes are enqueued.

It's important to handle the case where the top previous and the top new keys are the same, typically it is implemented as no-op.

if(stateChange.isTopNewKeyEqualToPrevious()) {
    completionCallback.stateChangeComplete();
    return;
}
// handle state change
completionCallback.stateChangeComplete();