Final Results
Your nav_graph
navigation resource should resemble:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph.xml"
app:startDestination="@id/rosterListFragment">
<fragment
android:id="@+id/rosterListFragment"
android:name="com.commonsware.todo.RosterListFragment"
android:label="@string/app_name">
<action
android:id="@+id/displayModel"
app:destination="@id/displayFragment" />
</fragment>
<fragment
android:id="@+id/displayFragment"
android:name="com.commonsware.todo.DisplayFragment"
android:label="@string/app_name" >
<argument
android:name="modelId"
app:argType="string" />
<action
android:id="@+id/editModel"
app:destination="@id/editFragment" />
</fragment>
<fragment
android:id="@+id/editFragment"
android:name="com.commonsware.todo.EditFragment"
android:label="@string/app_name" >
<argument
android:name="modelId"
app:argType="string" />
</fragment>
</navigation>
The new actions_display
resource should have this XML:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/edit"
android:icon="@drawable/ic_edit"
android:title="@string/menu_edit"
app:showAsAction="ifRoom|withText" />
</menu>
The new todo_edit
layout resource should resemble:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/isCompleted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="@+id/desc"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/desc" />
<EditText
android:id="@+id/desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:ems="10"
android:hint="@string/desc"
android:inputType="text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/isCompleted"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/notes"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:ems="10"
android:gravity="start|top"
android:hint="@string/notes"
android:inputType="textMultiLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/desc"
app:layout_constraintVertical_bias="0.505" />
</androidx.constraintlayout.widget.ConstraintLayout>
DisplayFragment
should look like:
package com.commonsware.todo
import android.os.Bundle
import android.text.format.DateUtils
import android.view.*
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.commonsware.todo.databinding.TodoDisplayBinding
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
class DisplayFragment : Fragment() {
private val args: DisplayFragmentArgs by navArgs()
private var binding: TodoDisplayBinding? = null
private val motor: SingleModelMotor by viewModel { parametersOf(args.modelId) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = TodoDisplayBinding.inflate(inflater, container, false)
.apply { binding = this }
.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
motor.getModel()?.let {
binding?.apply {
completed.visibility = if (it.isCompleted) View.VISIBLE else View.GONE
desc.text = it.description
createdOn.text = DateUtils.getRelativeDateTimeString(
requireContext(),
it.createdOn.toEpochMilli(),
DateUtils.MINUTE_IN_MILLIS,
DateUtils.WEEK_IN_MILLIS,
0
)
notes.text = it.notes
}
}
}
override fun onDestroyView() {
binding = null
super.onDestroyView()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.actions_display, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.edit -> {
edit()
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun edit() {
findNavController().navigate(
DisplayFragmentDirections.editModel(
args.modelId
)
)
}
}
EditFragment
at this point should resemble:
package com.commonsware.todo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import com.commonsware.todo.databinding.TodoEditBinding
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
class EditFragment : Fragment() {
private var binding: TodoEditBinding? = null
private val args: EditFragmentArgs by navArgs()
private val motor: SingleModelMotor by viewModel { parametersOf(args.modelId) }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = TodoEditBinding.inflate(inflater, container, false)
.apply { binding = this }
.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
motor.getModel()?.let {
binding?.apply {
isCompleted.isChecked = it.isCompleted
desc.setText(it.description)
notes.setText(it.notes)
}
}
}
override fun onDestroyView() {
binding = null
super.onDestroyView()
}
}
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.