I am working on an Todo-list as an android app to get started with Kotlin, but I am running into the problem, that my TodoAdapter class (which is supposed to define what to do with said Todos in a recyclerview as far as I understood?) can't inherit from the ListAdapter class for some reason.
I believe I didn't have the problem before I tried to add persistence to my app by saving to a simple .txt-file as a start. Please have a look at my code below and help me fix my code.
My TodoAdapter class:
class TodoAdapter (
private val todos: MutableList<Todo>
) : ListAdapter<Todo,TodoAdapter.TodoViewHolder>() {
class TodoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
return TodoViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_todo,
parent,
false
)
)
}
fun addTodo(todo: Todo) {
todos.add(todo)
notifyItemInserted(todos.size - 1)
}
fun deleteDoneTodos() {
todos.removeAll { todo ->
todo.isChecked
}
notifyDataSetChanged()
}
private fun toggleStrikeThrough(tvTodoTitle: TextView, isChecked: Boolean) {
if (isChecked) {
tvTodoTitle.paintFlags = tvTodoTitle.paintFlags or STRIKE_THRU_TEXT_FLAG
} else{
tvTodoTitle.paintFlags = tvTodoTitle.paintFlags and STRIKE_THRU_TEXT_FLAG.inv()
}
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val curTodo = todos[position]
holder.itemView.apply {
tvTodoTitle.text = curTodo.title //Hier stimmt etwas nicht: tvTodoTitle Import fehlt???
cbDone.isChecked = curTodo.isChecked
toggleStrikeThrough(tvTodoTitle, curTodo.isChecked)
cbDone.setOnCheckedChangeListener{ _, isChecked ->
toggleStrikeThrough(tvTodoTitle, isChecked)
curTodo.isChecked = !curTodo.isChecked
}
}
}
override fun getItemCount(): Int {
return todos.size
}
My data class Todo:
data class Todo(
val title: String,
var isChecked: Boolean = false
)
And this is the code in my MainActivity.kt I tried to add persistence with:
private fun setupInternalStorageRecyclerView() = binding.rvTodoItems.apply {
adapter = todoAdapter
layoutManager = rvTodoItems.layoutManager
}
private fun loadTodoItemsFromInternalStorageIntoRecyclerView() {
lifecycleScope.launch {
val todoItems = loadTodoItemsFromInternalStorage()
todoAdapter.submitList(todoItems)
}
}
private suspend fun loadTodoItemsFromInternalStorage(): List<Todo> {
return withContext(Dispatchers.IO) {
val todoItemList: MutableList<Todo> = mutableListOf<Todo>()
val files = filesDir.listFiles()
files?.filter { it.canRead() && it.isFile && it.name.endsWith(".txt") }?.map {
val lines = it.bufferedReader().readLines()
for (i in lines.indices step 2) {
todoItemList.add(Todo(lines[i], lines[i+1].toBoolean()))
}
todoItemList
} ?: mutableListOf<Todo>()
} as MutableList<Todo>
}
private fun saveTodoItemsToInternalStorage(filename: String, todoItems: List<Todo>): Boolean {
return try{
openFileOutput("$filename.txt", MODE_PRIVATE).use { stream ->
File(filename).printWriter().use { out ->
for (item in todoItems) {
out.println(item.title)
out.println(item.isChecked)
}
}
}
true
} catch(e: IOException) {
e.printStackTrace()
false
}
}
I hope this is enough information to help me with, feel free to ask for more information, I will gladly provide it.