sorry for the English, I'm using a translator.i'm just a beginner, please consider this when replying.i know the code may not be the best. this is just a start. I'm using the viewmodel to create a template and then use this template in several instances,the problem is that when you enter a value in the field for item 1, the other field is also filled at the same time. I'd like to know the error, and why the code isn't working even though I've created different instances.
main file:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MercadoTheme {
Aplicacao()
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Aplicacao(modifier: Modifier = Modifier) {
val item1VM: ItemInputViewModel = viewModel()
val item2VM: ItemInputViewModel = viewModel()
val item1Layout = ItemInput()
val item1State by item1VM.itemState.collectAsState()
val item2Layout = ItemInput()
val item2State by item2VM.itemState.collectAsState()
Scaffold(modifier.fillMaxSize(),
topBar = {
TopAppBar(
modifier = modifier.fillMaxWidth(),
title = {
Text(
modifier = modifier.fillMaxWidth(),
text = "Comparador de Preços",
color = CompareTopAppBarTextColor,
fontWeight = FontWeight.Bold,
fontSize = 25.sp,
textAlign = TextAlign.Center,
)
},
colors = TopAppBarDefaults.topAppBarColors(CompareTopAppBarBackgroundColor)
)
},
content = { innerPadding ->
Column(modifier = Modifier.padding(innerPadding)) {
item1Layout.Insert(
itemData = item1State,
onValorChange = { item1State.onValorChange(it) },
onQuantidadeChange = { item1State.onQuantidadeChange(it) },
onUnidadeChange = { item1State.onUnidadeChange(it) },
onExpandedChange = { item1State.onExpandedChange(it) }
)
//---------------
Spacer(modifier = Modifier.size(20.dp))
item2Layout.Insert(
itemData = item2State,
onValorChange = { item2State.onValorChange(it) },
onQuantidadeChange = { item2State.onQuantidadeChange(it) },
onUnidadeChange = { item2State.onUnidadeChange(it) },
onExpandedChange = { item2State.onExpandedChange(it) }
)
}
})
}
UI file:
class ItemInput {
@Composable
fun Insert(
modifier: Modifier = Modifier,
itemData: ItemData,
onValorChange: (String) -> Unit = {},
onQuantidadeChange: (String) -> Unit = {},
onUnidadeChange: (String) -> Unit = {},
onExpandedChange: (Boolean) -> Unit = {}
) {
var textFieldSize by remember { mutableStateOf(Size.Zero) }
val unidadesOptions = listOf("-", "Kg", "g", "L", "mL", "m", "Cm", "mm")
Column {
Text(
modifier = modifier
.padding(10.dp)
.align(Alignment.CenterHorizontally),
text = itemData.name,
style = MaterialTheme.typography.titleLarge
)
Row(
modifier = modifier.padding(10.dp),
content = {
// Valor
OutlinedTextField(
modifier = Modifier.weight(3f),
singleLine = true,
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
label = { Text("Valor") },
value = itemData.valor,
onValueChange = onValorChange
)
Spacer(modifier = Modifier.width(8.dp))
// Quantidade
OutlinedTextField(
modifier = Modifier.weight(3f),
singleLine = true,
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
label = { Text("Quantidade") },
value = itemData.quantidade,
onValueChange = onQuantidadeChange
)
Spacer(modifier = Modifier.width(8.dp))
// Unidade
OutlinedTextField(
readOnly = true,
value = itemData.unidade,
onValueChange = {},
label = { Text("Unidade") },
trailingIcon = {
Icon(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = "Open dropdown",
modifier = Modifier.size(24.dp)
)
},
modifier = Modifier
.weight(2f)
.onGloballyPositioned { coordinates ->
textFieldSize = coordinates.size.toSize()
}
.clickable { onExpandedChange(true) }
)
// Menu
DropdownMenu(
expanded = itemData.expanded,
onDismissRequest = { onExpandedChange(false) },
modifier = Modifier
.width(textFieldSize.width.dp)
.padding(top = 8.dp)
) {
unidadesOptions.forEach { item ->
DropdownMenuItem(
text = { Text(item) },
onClick = {
onUnidadeChange(item)
onExpandedChange(false)
}
)
}
}
}
)
}
}
}
VM file:
data class ItemData(
val name: String = "Item",
val valor: String = "",
val quantidade: String = "",
val unidade: String = "-",
val expanded: Boolean = false,
val onNameChange: (String) -> Unit = {},
val onValorChange: (String) -> Unit = {},
val onQuantidadeChange: (String) -> Unit = {},
val onUnidadeChange: (String) -> Unit = {},
val onExpandedChange: (Boolean) -> Unit = {}
)
class ItemInputViewModel : ViewModel() {
private val _itemState = MutableStateFlow(ItemData())
val itemState = _itemState.asStateFlow()
init {
_itemState.update { currentState ->
currentState.copy(
onNameChange = { newValue ->
_itemState.value = _itemState.value.copy(name = newValue)
},
onValorChange = { newValue ->
_itemState.value = _itemState.value.copy(valor = newValue)
},
onQuantidadeChange = { newValue ->
_itemState.value = _itemState.value.copy(quantidade = newValue)
},
onUnidadeChange = { newValue ->
_itemState.value = _itemState.value.copy(unidade = newValue)
},
onExpandedChange = { newValue ->
_itemState.value = _itemState.value.copy(expanded = newValue)
}
)
}
}
}
I've tried passing the parameters like this, but the same error still occurs
fun Aplicacao(modifier: Modifier = Modifier,
item1VM: ItemInputViewModel = viewModel(),
item2VM: ItemInputViewModel = viewModel()
)