如何在 Jetpack Compose 中用 Data Class 中的字段填充 TextView?

How to fill in the TextViews with a field in a Data Class in Jetpack Compose?

所以我参与的这个项目让我第一次使用 Jetpack Compose 创建我的布局。所以我对此很陌生。我有数据 类,其中存储了来自 API 的数据。 ViewModel/LiveData 也在使用中。我的问题是如何让 TextView 显示存储在数据模型中的数据?欢迎任何和所有答案。谢谢。

首先,通过viewModel()为您的屏幕创建一个ViewModel。例如

val myViewModel: MyViewModel = viewModel()

val myViewModel: MyViewModel = hiltViewModel()

对于 DaggerHilt。 (如果您无法访问这些功能,请尝试为 viewModel() 添加 androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1 并为 hiltViewModel() 添加 androidx.hilt:hilt-navigation-compose:1.0.0 — 请注意这些版本可能已过时)。

接下来,将您的存储库或用例传递或注入到 ViewModel 的构造函数中,并创建一个状态变量来保存和更新您的文本。

@HiltViewModel
class MyViewModel @Inject constructor(
  private val myRepository: MyRepository
): ViewModel() {

  var text by mutableStateOf("")
    private set

  fun setNewText(newText: String) {
    text = newText
  }

  init {
    viewModelScope.launch { // in case it's a suspend function
      setNewText(myRepository.getDataClass().getText())
    }
  }
}

(对于mutableStateOf getter和setter委托,需要导入androidx.compose.runtime.getValueandroidx.compose.runtime.setValue)。

最后,在您的 Composable 函数中创建 Text,调用 ViewModel 并使用它来更新您新创建的文本。

@Composable
fun MyScreen(myViewModel: MyViewModel = hiltViewModel()) {
  Text(
    text = myViewModel.text,
    modifier = Modifier.fillMaxWidth() // modify it as you wish
  )
}

如果这不符合您的需要,请提供有关您的情况的更多详细信息。 此外,如果您对我向您展示的内容有任何疑问,我建议您查看 the documentation

我不知道你是从哪里找到你描述的方法的,但你需要的是 state-hoisting。

可以找到基本原则 here。这就是它的工作原理。

假设您将变量存储在视图模型中,

var text by mutableStateOf("Initial Value Here") // Use 'by' to avoid writing '.value' every time

现在,您需要在您的 viewModel 中创建一个方法来更新此变量——任何希望修改此变量的代码都可以调用该方法。

var text by mutableStateOf("Initial Value Here")
fun updateText(newText: String){
  text = newText
}

现在,在您的可组合项中,创建两个参数——一个用于获取值,另一个用于设置它。

@Composable
fun MyTextView(
 text: Int,
 onTextUpdate: (String) -> Unit // It accepts 'String' and returns 'Unit', like 'void' in java
){

 TextField(
    value = text, //Use the Value Here as a normal value,
    onValueChange = onTextUpdate // Pass this as the updating function
 )

}

在调用站点,传递 viewModel 的参数以连接 state-hoisting 节点,就像这样。

setContent{
  val viewmodel = ... //Initialize ViewModel Here
  MyTextField(viewmodel.text, viewmodel::updateText)
}

差不多就是这样。您只需要一个变量并进行修改即可为您完成所有繁重的工作——无需像上面提到的那样处理多个变量。

考虑参加 the codelabs