I am making a to do list and I am using multiple type recyclerview for it. If the task in the list has not been done, if it has been done under the Active title, it will be under the Done title. So I need to put two Headers for Active and Done headers, but I couldn't do this. I would be glad if you help.
I drew a picture to explain better. I want to add Active and Done headers here.
Adapter Class
class ToDoListAdapter(var onItemClicked: ((item: ToDoData) -> Unit?)? = null) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val VIEW_TYPE_ACTIVE = 1
const val VIEW_TYPE_DONE = 2
}
var dataList = emptyList<ToDoData>()
class MyViewHolderActive(val binding: RowItemActiveBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(toDoData: ToDoData) {
binding.toDoData = toDoData
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): MyViewHolderActive {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = RowItemActiveBinding.inflate(layoutInflater, parent, false)
return MyViewHolderActive(binding)
}
}
}
class MyViewHolderDone(val binding: RowItemDoneBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(toDoData: ToDoData) {
binding.toDoData = toDoData
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): MyViewHolderDone {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = RowItemDoneBinding.inflate(layoutInflater, parent, false)
return MyViewHolderDone(binding)
}
}
}
override fun getItemViewType(position: Int): Int {
return dataList[position].viewType
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == VIEW_TYPE_ACTIVE) {
return MyViewHolderActive.from(parent)
}
return MyViewHolderDone.from(parent)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val currentItem = dataList[position]
if (currentItem.viewType == VIEW_TYPE_ACTIVE) {
(holder as MyViewHolderActive).bind(currentItem)
holder.binding.imageViewDeleteActive.setOnClickListener {
onItemClicked?.invoke(currentItem)
}
} else {
(holder as MyViewHolderDone).bind(currentItem)
holder.binding.imageViewDeleteDone.setOnClickListener {
onItemClicked?.invoke(currentItem)
}
}
}
override fun getItemCount(): Int {
return dataList.size
}
fun setData(newList: List<ToDoData>) {
this.dataList = newList
notifyDataSetChanged()
}
}
Model class
data class ToDoData(
var id: Int,
var viewType: Int,
var title: String,
var description: String
)
ToDoFragment
class ToDoFragment : Fragment() {
private var _binding: FragmentToDoBinding? = null
private val binding get() = _binding!!
private val toDoViewModel: ToDoViewModel by viewModels()
private val adapter: ToDoListAdapter by lazy { ToDoListAdapter() }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentToDoBinding.inflate(inflater, container, false)
setAdapter()
toDoViewModel.getAllData.observe(viewLifecycleOwner, { data ->
adapter.setData(data)
})
binding.buttonAddTask.setOnClickListener {
addTaskToDatabase()
}
return binding.root
}
private fun addTaskToDatabase() {
val title = binding.editTextTitle.text.toString()
val description = binding.editTextDescription.text.toString()
val newTask = ToDoData(0, 1, title, description)
toDoViewModel.insertData(newTask)
clearInputFields()
}
private fun clearInputFields() {
binding.editTextTitle.text.clear()
binding.editTextDescription.text.clear()
}
private fun setAdapter() {
val recyclerView = binding.recyclerViewTasks
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
adapter.apply {
onItemClicked = { currentItem ->
toDoViewModel.deleteOrUpdateData(currentItem)
}
}
}
}