Step #4: Launching the EditFragment for Adds

Next, we need to add some logic to do some work when the user taps that “add” app bar item. Specifically, we want to navigate from the RosterListFragment to the EditFragment… but do so in a way that tells the EditFragment that we should be adding a new to-do item, not editing an existing one.

Right now, to navigate to the EditFragment, we need to provide a modelId value, identifying the existing to-do item to be edited. In this case, though, we do not have an existing to-do item — we want to create a new one. So, we can change the navigation graph to allow modelId to support null as a value. Then, we can have a null modelId indicate that we are creating a new to-do item, while a non-null modelId would indicate that we are editing an existing to-do item.

With all that in mind, open res/navigation/nav_graph.xml, and click on the editFragment destination. In the “Attributes” pane, we have our modelId argument. Double-click on it to bring up a dialog to update its configuration:

Android Studio Navigation Editor, Update Argument Link Dialog
Android Studio Navigation Editor, Update Argument Link Dialog

Check the “Nullable” checkbox, then click Update to close the dialog.

Next, click on the rosterListFragment destination. Using the circle on the right edge, drag a new action, connecting it to editFragment. When you have done that, you may want to click the toolbar button that looks like… well… plusses or stars or something. It will “auto-arrange” the destinations to help make the actions more visible:

Android Studio Navigation Editor, With Auto-Arrange Toolbar Button Highlighted
Android Studio Navigation Editor, With Auto-Arrange Toolbar Button Highlighted

In the “Attributes” pane for this new action, set the ID to createModel. Then, there should be an “Argument Default Values” section, showing modelId. Fill in @null in the “default value” field, where @null means “no, I really mean null, and not the string "null"”.

From the Android Studio main menu, choose “Build” > “Make Module ‘app’” to get Android Studio to generate fresh Safe Args code for our navigation resource.

Next, add this add() function to RosterListFragment:

  private fun add() {
    findNavController().navigate(RosterListFragmentDirections.createModel(null))

This does the same sort of thing as display(), except that it uses the createModel() action instead of the displayModel() action.

Then, add this onOptionsItemSelected() function to RosterListFragment:

  override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
      R.id.add -> {
        add()
        return true
      }
    }

    return super.onOptionsItemSelected(item)

If the user clicks the add app bar item, we call the add() function.

If you run the app and click the new “Add” action bar item… you should crash. Specifically, you will get an error from Kotlin, complaining that something was null but was declared to be not-null.

That error is coming from this line in SingleModelMotor:

  private val modelId: String

We declared this constructor parameter as taking String, and that used to work. But now we allow our modelId to be null to represent the case where we are creating a new model. To fix that, change that parameter to be String? instead of String:

class SingleModelMotor(
  private val repo: ToDoRepository,
  private val modelId: String?
) : ViewModel() {

That, in turn, gives you an error in the getModel() function, as find() on ToDoRepository is set to take a String parameter, not String?. So, adjust find() on ToDoRepository to take String? instead:

  fun find(modelId: String?) = items.find { it.id == modelId }

The implementation of find() does not need to change; it will simply return null when none of the items matches the null ID.

Now, if you run the app and click the “add” app bar item, you should get an empty EditFragment form, showing our hints for the description and notes fields:

ToDo App, Showing Empty Form
ToDo App, Showing Empty Form

If you run the sample app, click the “add” app bar item, fill in the form, and click the “save” app bar item, you wind up seeing the list of to-do items… with the empty text still visible:

ToDo App, Showing Both an Item and the Empty Text
ToDo App, Showing Both an Item and the Empty Text

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.