Пользовательский интерфейс не обновляется должным образом при первом запуске приложения Android Compose

У меня есть следующий код в моей HomePageViewModel:

      private val _overallStitchCount: MutableStateFlow<Int> = MutableStateFlow(0)
    val overallStitchCount: StateFlow<Int> = _overallStitchCount

...

init {
        projectRepo = projectRepository
        projectRepo.refreshProjectData()
        populateValues()
    }

    fun populateValues() {
        _overallStitchCount.value = projectRepo.projectData.value.size
    }

    fun addProject() {
        val projectCount = projectRepo.projectData.value.size

        projectRepo.addProject(
            project = Project(
                uid = projectCount,
                projectName = "Example Project $projectCount"
            ),
            callback = { populateValues() }
        )
    }

Как видите, я использую commonStitchCount, чтобы проверить, что содержится в моей базе данных. Вот что у меня есть в классе ProjectRepository:

      private val _projectData: MutableStateFlow<List<Project>> = MutableStateFlow(listOf())
    val projectData: StateFlow<List<Project>> = _projectData

...

init {
        CoroutineScope(Dispatchers.IO).launch {
            val data = getAllProjects()

            if(data.isEmpty()) {
                Log.i(LOG_TAG, "Generating example project data.")
                generateExampleProjectData()
            }
            else {
                _projectData.value = data
            }
        }
    }

...

fun addProject(
        project: Project,
        callback: (() -> Unit)? = null,
    ) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                projectDao.addProject(project)
                _projectData.value = getAllProjects()
                if(callback != null) callback()
            }
            catch(e: Exception) {
                Log.e(LOG_TAG, "Exception: Could not create project ${project.projectName}. Reason: ${e.message}")
            }
        }
    }

    private fun generateExampleProjectData() {
        val project = Project(
            uid = 0,
            projectName = "Example Project"
        )
        addProject(
            project = project,
        )
    }

    fun refreshProjectData(
    ) {
        CoroutineScope(Dispatchers.IO).launch {
            val data = getAllProjects()

            if(data.size != _projectData.value.size) {
                Log.i(LOG_TAG, "Projects has changed, refreshing.")
                _projectData.value = getAllProjects()
            }
        }
    }

    fun getAllProjects(): MutableList<Project> {
        return try {
            projectDao.getAll()
        } catch(e: Exception) {
            Log.e(LOG_TAG, "Exception: ${e.message}")
            mutableListOf()
        } catch(e: SQLiteException) {
            Log.e(LOG_TAG, "Exception: ${e.message}")
            mutableListOf()
        }
    }

Теперь при первом запуске моего приложения количество стежков в моем пользовательском интерфейсе равно 0. В этот момент должно быть указано 3.

Однако в тот момент, когда я нажимаю кнопку «Добавить проект» в своем пользовательском интерфейсе, если количество баз данных равно 3, тогда будет указано 4, что будет правильно.

Как мне изменить код, чтобы правильно обновляться при первом запуске и читать правильный счетчик в базе данных?

1 ответ

Я наконец-то это исправил (думаю). Я изменилProjectRepositoryметод к полноценной функции вместо этого с помощью обратного вызова, например:

      fun init(
        callback: (() -> Unit)? = null,
    ) {
        CoroutineScope(Dispatchers.IO).launch {
            val data = getAllProjects()

            if(data.isEmpty()) {
                Log.i(LOG_TAG, "Generating example project data.")
                generateExampleProjectData()
            }
            else {
                _projectData.value = data
            }
            
            if(callback != null) callback()
        }
    }

Затем я сделал следующее со своимHomePageViewModel init:

      init {
        projectRepo = projectRepository
        projectRepo.init(
            callback = { populateValues() }
        )
    }

Теперь он обновляется, как я и ожидал, при запуске моего приложения. вместе с любыми дальнейшими обновлениями, которые у меня могут быть.

Другие вопросы по тегам