如何在 Kotlin 中从 textField 获取值到 viewmodel

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

我有这样的用户界面:

有一个产品列表,每个产品都有一个变体列表。用户输入他需要的变体数量,然后单击“下订单”按钮。

用户界面:

这是我用过的数据类

data class VariantModal(
    val variantId: String,
    val variantName: String,
    val variantUnit: VariantUnit,
    val productId: String,
    val variantQuantity: Int,
    )


data class Product(
    val productId: String,
    val productName: String,
    val productVariants: List<VariantModal>,
)

这是我的列表的示例:

object SampleProductData {
var items = listOf(
    Product(
        "1_pg",
        "Puliogare Masala",
        listOf(
            VariantModal(
                "pg_30_7",
                "30g 7sheet",
                VariantUnit.ListOfUnits(listOf("Bundle", "Kg")),
                "1_pg",
                0
            ),
            VariantModal(
                "pg_30_14",
                "30g 14sheet",
                VariantUnit.ListOfUnits(listOf("Bundle", "Kg")),
                "1_pg",
                0
            ),
            VariantModal(
                "pg_100",
                "100g",
                VariantUnit.ListOfUnits(listOf("Bundle", "Kg")),
                "1_pg",
                0
            ),
        )
    ),
     Product(....similar to above...),
     Product(....similar to above...),
     Product(....similar to above...),

   )
}

我正在从数据库中获取产品和变体列表,并在视图模型中使用它。

@HiltViewModel
class ProductsListViewModel @Inject constructor(
    private val repository: ProductsRepository
) : ViewModel() {


private val itemsList = MutableStateFlow(listOf<Product>())
val items: StateFlow<List<Product>> get() = itemsList
val initialOrder: StateFlow<List<Product>> get() = itemsList

private val itemIdsList = MutableStateFlow(listOf<Int>())
val itemIds: StateFlow<List<Int>> get() = itemIdsList

init {
    init()
}
private fun init() = viewModelScope.launch {
    getData()
}

private suspend fun getData() {
    val products = repository.getAllProducts()
    viewModelScope.launch {
        withContext(Dispatchers.Default) {
            itemsList.emit(products)

            Log.d("Console statement", "itemsList is ${itemsList.value}")
            Log.d("Console statement", "items are ${items.value}")
        }
    }
}

fun onItemClicked(itemId: Int) {
    itemIdsList.value = itemIdsList.value.toMutableList().also { list ->
        if (list.contains(itemId)) {
            list.remove(itemId)
        } else {
            list.add(itemId)
        }
    }
}


fun placeOrder(context: Context, viewModel: ProductsListViewModel) = viewModelScope.launch  {
    Log.d("Console Statement", "button clicke ${viewModel.items.value} ")
    Toast.makeText(context, "Button clicked ", Toast.LENGTH_LONG).show()
}
   }

现在,我想获取用户输入的数量值,并将其存储在用户单击“下订单”按钮时的variantQuantity中。

我将所有产品显示为这样的列表:

@Composable
    fun ProductsList(viewModel: ProductsListViewModel) {
    val itemIds by viewModel.itemIds.collectAsState()
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Scaffold(
            topBar = { TopBar(viewModel) }
        ) { padding ->
            LazyColumn(
                modifier = Modifier
                    .padding(padding)
            ) {

                itemsIndexed(viewModel.items.value) { index, item ->
                    DisplayProduct(
                        itemModel = item,
                        onClickItem = { viewModel.onItemClicked(index) },
                        expanded = itemIds.contains(index)
                    )
                }
            }
        }
    }
}

DisplayProduct 方法调用 DisplayVariants 方法来显示每个变体。 DisplayVariant 方法具有我想要获取其值的文本字段。我展示了最少的代码以保持简单,

@Composable
fun displayVariant(
    item: Product,
    variant: VariantModal,
) {
    var orderedQuantity = 0
    var value by remember {
        mutableStateOf("")
    }
    TextField(
//        value = variant.variantQuantity.toString(), //This is not working
        value = value,
        colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White),
        modifier = Modifier
            .widthIn(min = 32.dp),
        onValueChange = { newText ->
            value = newText

        },
        keyboardOptions = KeyboardOptions(
            capitalization = KeyboardCapitalization.None,
            autoCorrect = false,
            keyboardType = KeyboardType.Number,
            imeAction = ImeAction.Done
        )

    )
    if(value != "" ){
        orderedQuantity = value.toInt()
    }
//    updateOrderQuanity(variant, orderedQuantity)
    Log.d("Console Statement", "${variant.variantName}  $value  order placed " )
}

我试过了

value = variant.variantQuantity.toString()

保存用户在variant.variantQuantity中输入的值,但这不起作用。它依次设置 value 中的variant.variantQuantity value`。如何将用户输入的值保存到variant.variantQuantity?我需要这个,因为我想在单击“PlaceOrder”按钮下订单时发送带有变体的产品列表及其变体数量:

PlaceOrder的onClick是这样的:

 Button(
     onClick = { viewModel.placeOrder(context, viewModel) }
     )
     { Text("Place Order") }

总而言之,我有一个产品列表,每个产品都有一个变体列表。产品和变体的数量每次都不是固定的。我正在从数据库获取数据并使用视图模型。然后我将数据呈现为产品列表。我想将用户输入的数据(变量数量 - 文本字段)发送回视图模型,以便我可以在 PlaceOrder 功能中使用它。如何实现这一目标。

android kotlin android-jetpack-compose viewmodel
1个回答
0
投票

我猜你需要视图模型中的另一个变量来包含文本字段的值,还添加一个函数来更新视图模型中变量的值。 它会像这样工作:

点击元素 -> 更改包含文本字段值的子变量 -> 点击订单按钮 -> 从视图模型调用函数,该函数将更新视图模型中的变量

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