Issue
I'm not sure if I've described my problem accurately. My problem is that I have this LazyColumn:
LazyColumn {
items(state.matches) {match->
MatchItem(
match = match,
vm = vm
)
}
}
}
In above lines I'm fetching data from API. In this case I'm getting a list of Match, it contains some information about some soccer matches.
So the problem is that I want the user to predict the result of each match.
@Composable
fun ResultText(
showText: Boolean,
result: ResultState,
onResultChanged: (Int) -> Unit
) {
if (showText) {
Text(text = result, fontSize = MaterialTheme.typography.body2.fontSize)
} else {
ResultPicker(onResultChanged = onResultChanged)
}
}
But I can't seem to find a way to add the prediction in every single match because it is seperated from the data which I'm fetching. Is there's a way do that?
EDIT:
MatchItem composable:
@Composable
fun MatchItem(
match: Match,
result: ResultState,
vm: HomeViewModel
) {
Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceAround
) {
TeamInfo(
team = match.team1,
painter = flag1,
horizontal = Alignment.CenterHorizontally,
vertical = Arrangement.Top
)
ResultText(
showText = (textOrPicker == ShowTextOrPicker.TEXT),
result = result.team1,
onResultChanged = {
vm.changeResult(result = ResultState(
team1 = it.toString(),
team2 = result.team2
)
)
}
)
Text(
modifier = Modifier.padding(vertical = 10.dp),
text = "VS",
textAlign = TextAlign.Center,
fontSize = 20.sp
)
TeamInfo(
team = match.team2,
painter = flag2,
horizontal = Alignment.CenterHorizontally,
vertical = Arrangement.Bottom
)
ResultText(
showText = (textOrPicker == ShowTextOrPicker.TEXT),
result = result.team2,
onResultChanged = {
vm.changeResult(result = ResultState(
team1 = result.team2,
team2 = it.toString()
)
)
}
)
}
ResultState:
data class ResultState(
val team1:String = "-",
val team2:String = "-"
)
And in viewmodel:
private val _resultState =
mutableStateOf<List<ResultState>>(emptyList())
val resultState = _resultState
Solution
Instead of using a List<ResultState>
to store predictions for matches, you could store them in a Map<Any, ResultState>
. The key could be the match id (if you have one) or you could make a key from some parameters that uniquely identify a match. You can use a Pair
to create a key from 2 parameters or a Triple
to create a key from 3 parameters. If you would need more than 3 parameters to create a unique key, then you can use a data class
to represent your key or hash the parameters yourself to get the value for the key.
So the state would change to a Map<Any, ResultState>
and changeResult
would change to also accept a key
as a parameter
class HomeViewModel : ViewModel() {
var resultState: Map<Any, ResultState> by mutableStateOf(emptyMap())
private set
fun changeResult(key: Any, result: ResultState) {
resultState = resultState.plus(Pair(key, result))
}
}
Then in your MatchItem
you retrieve the ResultState
using the key and also pass the key into the vm.changeResult
calls.
@Composable
fun MatchItem(
match: Match,
vm: HomeViewModel
) {
// if your Match data has any unique identifier use it as the key
// val key = match.id
// otherwise, just use a Pair/Triple of parameters that create something unique
val key = Pair(match.team1, match.team2)
val result = vm.resultState[key] ?: ResultState()
// ...
ResultText(
showText = (textOrPicker == ShowTextOrPicker.TEXT),
result = result.team1,
onResultChanged = {
vm.changeResult(
// add the key to the changeResult call
key = key,
result = ResultState(
team1 = it.toString(),
team2 = result.team2
)
)
}
)
// ...
ResultText(
showText = (textOrPicker == ShowTextOrPicker.TEXT),
result = result.team2,
onResultChanged = {
vm.changeResult(
// add the key to the changeResult call
key = key,
result = ResultState(
team1 = result.team1,
team2 = it.toString()
)
)
}
)
}
Answered By - Ma3x
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.