LazyColumn not recomposing

47 Views Asked by At

[SOLVED: Check my answer] I checked some posts here and nothing works to me. My LazyColumn only recompose if I click in the FloatingActionButton for example. When I open the app nothing shows, and when I click on the Delete Button or Check Button the screen does not recompose. Can someone help me with what I am doing wrong?

ViewModel code:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.cleanarchtaskapp.feature_task.domain.use_case.TaskUseCases
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class TaskViewModel @Inject constructor(
    private val taskUseCases: TaskUseCases
) : ViewModel() {

    private val _state: MutableStateFlow<TaskState> = MutableStateFlow(TaskState())
    val state: StateFlow<TaskState> get() = _state

    private var getTaskJob: Job? = null

    init {
        getTaskList()
    }

    fun onEvent(event: TaskEvent) {
        when (event) {
            is TaskEvent.CheckTask -> {
                viewModelScope.launch {
                    taskUseCases.insertTaskUseCase(event.task)
                }
            }

            is TaskEvent.DeleteTask -> {
                viewModelScope.launch {
                    taskUseCases.deleteTaskUseCase(event.task)
                }
            }
        }
    }

    private fun getTaskList() {
        getTaskJob?.cancel()
        getTaskJob = taskUseCases.getAllTasksUseCase().onEach { tasks ->
            _state.value.taskList = tasks
        }.launchIn(viewModelScope)
    }

}

Screen code:

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import com.example.cleanarchtaskapp.feature_task.presentation.general.Screens
import com.example.cleanarchtaskapp.feature_task.presentation.tasks_screen.components.Task

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TaskScreen(
    modifier: Modifier = Modifier,
    navController: NavController,
    viewModel: TaskViewModel = hiltViewModel()
) {

    val state by viewModel.state.collectAsState()

    Scaffold(
        modifier = modifier.fillMaxSize(),
        floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    navController.navigate(route = Screens.AddEditTaskScreen.route)
                }
            ) {
                Icon(imageVector = Icons.Default.Add, contentDescription = "Add task.")
            }
        }
    ) {
        Column(
            modifier = Modifier.padding(it)
        ) {

            LazyColumn {
                items(items = state.taskList) { task ->
                    Task(
                        taskContent = task.taskContent,
                        checked = task.status,
                        onCheckedChange = {
                            viewModel.onEvent(TaskEvent.CheckTask(task.copy(status = !task.status)))
                        },
                        onDelete = {
                            viewModel.onEvent(TaskEvent.DeleteTask(task))
                        }
                    )
                }
            }

        }
    }

}
1

There are 1 best solutions below

0
On

To solve this error I just made this change in the ViewModel code:

From:

private fun getTaskList() {
        getTaskJob?.cancel()
        getTaskJob = taskUseCases.getAllTasksUseCase().onEach { tasks ->
            _state.value.taskList = tasks
        }.launchIn(viewModelScope)
    }

To:

private fun getTaskList() {
        getTaskJob?.cancel()
        getTaskJob = taskUseCases.getAllTasksUseCase().onEach { tasks ->
            _state.value = state.value.copy(taskList = tasks)
        }.launchIn(viewModelScope)
    }