I have a todo app and I am accessing my views with ViewBinding from my onBindViewHolder class. I put a function to check the state of a Boolean(a checkBox in this sense) and toggle a strikethrough on the TextView(Todo) based on the state of that Boolean. I also put a setOnCheckedChangeListener
to know when the state of the checkBox has been changed and assign that new state to my stored Boolean variable for the checkBox. However it is not working properly despite changing the Implementation several times. This is my code.
But first this is my class
@Entity(tableName = "todo_table")data class Todo( @PrimaryKey (autoGenerate = true) // here "Room" will autoGenerate the id for us // instead // of assigning a randomUUID value val id : Int = 0, var title : String = "", var date : Date = Date(), var time : Date = Date(), var todoCheckBox : Boolean = false)
And my Adapter
import android.annotation.SuppressLintimport android.graphics.Paint.STRIKE_THRU_TEXT_FLAGimport android.view.LayoutInflaterimport android.view.ViewGroupimport android.widget.TextViewimport androidx.recyclerview.widget.RecyclerViewimport androidx.recyclerview.widget.RecyclerView.Adapterimport com.bignerdranch.android.to_dolist.databinding.CustomRowBindingimport com.bignerdranch.android.to_dolist.fragments.add.SIMPLE_DATE_FORMATimport com.bignerdranch.android.to_dolist.fragments.add.SIMPLE_TIME_FORMATimport com.bignerdranch.android.to_dolist.model.Todoimport java.text.SimpleDateFormatimport java.util.Localeclass ListAdapter: Adapter<ListAdapter.TodoViewHolder>() { private var todoList = emptyList<Todo>() // will toggle strikeThrough on the Task title private fun toggleStrikeThrough(tvTaskTitle : TextView, cbTask : Boolean) { if (cbTask) { tvTaskTitle.paintFlags = tvTaskTitle.paintFlags or STRIKE_THRU_TEXT_FLAG } else { tvTaskTitle.paintFlags = tvTaskTitle.paintFlags or STRIKE_THRU_TEXT_FLAG.inv() }}inner class TodoViewHolder(val binding : CustomRowBinding) : RecyclerView.ViewHolder(binding.root)override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder { // this can be done in an inline variable and I may experiment on it later. val binding = CustomRowBinding.inflate(LayoutInflater.from(parent.context), parent, false ) return TodoViewHolder(binding)}override fun onBindViewHolder(holder: TodoViewHolder, position: Int) { val todo = todoList[position] val dateLocales = SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault()) val timeLocales = SimpleDateFormat(SIMPLE_TIME_FORMAT, Locale.getDefault()) holder.apply { binding.tvTaskTitle.text = todo.title binding.tvTaskDate.text = dateLocales.format(todo.date) binding.tvTaskTime.text = timeLocales.format(todo.time) binding.cbTask.isChecked = todo.todoCheckBox binding.cbTask.setOnCheckedChangeListener { _, isChecked -> toggleStrikeThrough(binding.tvTaskTitle, isChecked) todo.todoCheckBox = !todo.todoCheckBox } }}// as usual will return the size of the Listoverride fun getItemCount() = todoList.size@SuppressLint("NotifyDataSetChanged")fun setData(todo : List<Todo>) { this.todoList = todo // todo - This is a suppressed lint warning. Later check it online and see if there is a way to improve it. notifyDataSetChanged()}
}
Now this is the unusual behaviour when I run the App on my physical device or on my emulator. When I click on the CheckBox the strikeThrough appears but when I click on it again, the textView itself dissapears and the strikeThrough remains, and when I click on it again another strikeThrough appears making it two but with the textView still missing.
This is itImage may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
I have used different Implementations of the paintsFlag but its still not working. I also followed the exact same tutorial I used but still not working correctly with ViewBinding.