如何在协程内观察 Compose 中的实时数据

问题描述 投票:0回答:1

我正在练习撰写以及基于布局的应用程序,因为它是可互操作的

我在使用 RememberCoroutineScope 观察撰写屏幕内视图模型的实时数据时遇到问题。

考虑这是我的撰写屏幕:

版本屏幕.kt

package com.example.coroutinepractice.ui.composeUi.versionCompose

import android.util.Log
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.tooling.preview.Preview
import com.example.coroutinepractice.R
import com.example.coroutinepractice.requests.VersionRequestItem
import com.example.coroutinepractice.responses.Comments
import com.example.coroutinepractice.theme.PracticeTheme
import com.example.coroutinepractice.viewModels.MyViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

@Composable
fun VersionScreen() {
    var version by remember {
        mutableStateOf("")
    }
    val versionRequestItem = VersionRequestItem()
    val myViewModel = MyViewModel()
    val coroutineScope = rememberCoroutineScope()

    var status = myViewModel.comments.observeAsState().value

    Surface(
        modifier = Modifier
            .fillMaxHeight()
            .fillMaxWidth(), color = colorResource(id = R.color.black)
    ) {
        Column(
            modifier = Modifier.fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(text = version, color = colorResource(id = R.color.dark_yellow))
            Button(
                onClick = {
                    version =
                        callVersionApi(versionRequestItem, myViewModel, coroutineScope, status)
                },
                modifier = Modifier,
                colors = ButtonDefaults.buttonColors(colorResource(id = R.color.dark_yellow))
            ) {
                Text(text = "Click on me", color = colorResource(id = R.color.black))
            }
        }
    }

}

fun callVersionApi(
    versionRequestItem: VersionRequestItem,
    myViewModel: MyViewModel,
    coroutineScope: CoroutineScope,
    status: Comments?,
): String {
    var versionStatus: String = ""
    coroutineScope.launch(Dispatchers.Main) {
        versionRequestItem.Version_Name = "1"
        versionRequestItem.Version_Number = "1.0"
        versionRequestItem.Login = "GMM3671"
        myViewModel.getComments(versionRequestItem)
        val appVersion = status?.status
        if (appVersion != null) {
            versionStatus = appVersion
        }

    }
    return versionStatus
}


@Preview
@Composable
fun VersionScreenPreview() {
    PracticeTheme {
        VersionScreen()
    }
}

我的视图模型:

package com.example.coroutinepractice.viewModels

import androidx.databinding.ObservableField
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.coroutinepractice.data.repository.MyRepository
import com.example.coroutinepractice.requests.VersionRequestItem
import com.example.coroutinepractice.responses.Comments
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class MyViewModel @Inject constructor() : ViewModel() {
    private val myRepository = MyRepository()
    private val _comments = MutableLiveData<Comments>()
    val version = ObservableField<String>("")
    val comments: LiveData<Comments> = _comments

    suspend fun getComments(versionRequestItem: VersionRequestItem) =
        viewModelScope.launch(Dispatchers.IO) {
            val data = myRepository.getAppVersion(versionRequestItem)
            if (data.body() != null && data.isSuccessful) {
                _comments.postValue(data.body())
            }
        }

}

当我尝试通过撰写屏幕中的状态变量观察评论 liveData 时,尽管我的 api 向我发送了成功的响应,但我得到的结果为 null。我在这里做错了什么?

这是我在 logcat 中得到的响应:

2023-11-29 14:28:15.915 16057-16849 okhttp.OkHttpClient     com.example.coroutinepractice        I  {"status":0}

我想在单击带有文本“Click on me”的按钮时在文本框中显示状态值,即 0。

我尝试使用 LaunchedEffect(Unit) 并观察实时数据,它工作正常,但我想在单击按钮时点击 api。

当我导航到我的撰写屏幕(VersionScreen)时,使用启动的效果就会点击 api。我想在按钮点击时点击 api。

编辑:我刚刚通过点击按钮两次进行检查,我可以看到按钮上方文本上打印的数据为“0”。这意味着第一次它为空,然后我第二次点击 api 我可以看到数据。这可能是什么问题?

android android-studio android-jetpack-compose retrofit2 android-livedata
1个回答
0
投票

为什么不使用

var comments by mutableStateOf<Comments?>()

© www.soinside.com 2019 - 2024. All rights reserved.