ViewModel 更新后,Jetpack Composable 未更新(重绘)

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

我有一个 mutableStateListOf(ReturnItemExamples),列表中的每个对象都显示在 LazyColumn 中。

我遇到的问题是,一旦我使用 OutlinedTextField 更新数量,它会调用 API(在 viewModel 上)来更新记录,在 API 返回成功结果并将其更新到 mutableStateListOf(ReturnItemExamples) 列表之后,数量的更新未显示在 OutlinedTextField 中。我相信更新正在发生,并且它正在触发可组合项的重绘,因为我还有其他字段正在更新,唯一遇到问题的字段是 OutlinedTextField。这是唯一一个没有在屏幕上更新的。

这是具有数量属性的数据模型:

class ReturnItemExample (
    val itemCode: String? = null,
    val itemDescription: String? = null,
    var quantity: Int = 0
)

这是视图模型:

@HiltViewModel
class ReturnsViewModelExample @Inject constructor(
    val app: Application,
    val authToken: String,
    private val repository: ReturnsRepository,
) : AndroidViewModel(app) {

    val returnItems = mutableStateListOf<ReturnItemExample>()

    private fun updateReturnExample(quantity: Int, index: Int) {
        viewModelScope.launch {

        // Call to an API here returns the updated ReturnItemExample object and I update it here
        // with a function that sets the item from the API response to the item in the array at
        // the specified index
                    returnItems[index] = API.response

        }
    }
}

这是列表视图:

@Composable
fun ReturnsListViewExample(
    viewModel: ReturnsViewModelExample,
) {

    val itemIndex = remember { mutableIntStateOf(0) }

    Column {
        Box() {
            LazyColumn(state = rememberLazyListState()) {
                itemsIndexed(viewModel.returnItems) { index, _ ->
                    ReturnItemViewExample(
                        viewModel = viewModel,
                        itemIndex = index
                    )
                }
            }
        }
    }
}

这是显示我遇到问题的 OutlinedTextField 的可组合项:

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun ReturnItemViewExample(
    viewModel: ReturnsViewModelExample,
    itemIndex: Int
) {

    val keyboardController = LocalSoftwareKeyboardController.current
    val itemData = viewModel.returnItems[itemIndex]
    var testDisplayQuantity by remember { mutableStateOf(itemData.quantity.toString()) }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp)
            .padding(bottom = 8.dp),
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically
    ) {

        Text(
            text = "Test Quantity",
            fontSize = 14.sp,
            fontWeight = FontWeight.SemiBold,
            textAlign = TextAlign.Center
        )

        OutlinedTextField(
            value = testDisplayQuantity,
            onValueChange = { testDisplayQuantity = it },
            textStyle = LocalTextStyle.current.copy(fontSize = 14.sp),
            maxLines = 1,
            modifier = Modifier
                .fillMaxWidth(.5f)
                .padding(horizontal = 8.dp)
                .onKeyEvent {

                    if (it.nativeKeyEvent.keyCode == KeyEvent.KEYCODE_ENTER) {

                        if (validQuantity(testDisplayQuantity.toInt())) {
                            viewModel.updateReturnExample(testDisplayQuantity.toInt(), itemIndex)
                        }
                    }
                    true
                },
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Number,
                imeAction = ImeAction.Done
            ),
            keyboardActions = KeyboardActions(
                onDone = {
                    keyboardController?.hide()

                    if (validQuantity(testDisplayQuantity.toInt())) {
                        viewModel.updateReturnExample(testDisplayQuantity.toInt(), itemIndex)
                    }
                }),
            shape = RoundedCornerShape(10.dp)
        )
    }
}
android-jetpack-compose android-viewmodel
1个回答
0
投票

使用

MutableStateFlow
这是通知可组合状态的官方方式

您可以参考此博客探索 Jetpack Compose 中的 Kotlin 流程:强大的组合

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