Final Results
RosterRowHolder
should resemble:
package com.commonsware.todo
import androidx.recyclerview.widget.RecyclerView
import com.commonsware.todo.databinding.TodoRowBinding
class RosterRowHolder(
private val binding: TodoRowBinding,
val onCheckboxToggle: (ToDoModel) -> Unit
) :
RecyclerView.ViewHolder(binding.root) {
fun bind(model: ToDoModel) {
binding.apply {
isCompleted.isChecked = model.isCompleted
isCompleted.setOnCheckedChangeListener { _, _ -> onCheckboxToggle(model) }
desc.text = model.description
}
}
}
RosterAdapter
should look like:
package com.commonsware.todo
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.commonsware.todo.databinding.TodoRowBinding
class RosterAdapter(
private val inflater: LayoutInflater,
private val onCheckboxToggle: (ToDoModel) -> Unit
) :
ListAdapter<ToDoModel, RosterRowHolder>(DiffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
RosterRowHolder(
TodoRowBinding.inflate(inflater, parent, false),
onCheckboxToggle
)
override fun onBindViewHolder(holder: RosterRowHolder, position: Int) {
holder.bind(getItem(position))
}
}
private object DiffCallback : DiffUtil.ItemCallback<ToDoModel>() {
override fun areItemsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.isCompleted == newItem.isCompleted &&
oldItem.description == newItem.description
}
ToDoRepository
should resemble:
package com.commonsware.todo
class ToDoRepository {
var items = listOf(
ToDoModel(
description = "Buy a copy of _Exploring Android_",
isCompleted = true,
notes = "See https://wares.commonsware.com"
),
ToDoModel(
description = "Complete all of the tutorials"
),
ToDoModel(
description = "Write an app for somebody in my community",
notes = "Talk to some people at non-profit organizations to see what they need!"
)
)
fun save(model: ToDoModel) {
items = if (items.any { it.id == model.id }) {
items.map { if (it.id == model.id) model else it }
} else {
items + model
}
}
}
RosterMotor
should have:
package com.commonsware.todo
import androidx.lifecycle.ViewModel
class RosterMotor(private val repo: ToDoRepository) : ViewModel() {
val items = repo.items
fun save(model: ToDoModel) {
repo.save(model)
}
}
And RosterListFragment
should contain:
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.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.commonsware.todo.databinding.TodoRosterBinding
import org.koin.androidx.viewmodel.ext.android.viewModel
class RosterListFragment : Fragment() {
private val motor: RosterMotor by viewModel()
private var binding: TodoRosterBinding? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = TodoRosterBinding.inflate(inflater, container, false)
.also { binding = it }
.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = RosterAdapter(layoutInflater) {
motor.save(it.copy(isCompleted = !it.isCompleted))
}
binding?.items?.apply {
setAdapter(adapter)
layoutManager = LinearLayoutManager(context)
addItemDecoration(
DividerItemDecoration(
activity,
DividerItemDecoration.VERTICAL
)
)
}
adapter.submitList(motor.items)
binding?.empty?.visibility = View.GONE
}
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.