Reputation: 3008
I am using a LazyColumn
to populate items on my screen. I have a mutablelist
(), and a Text
composable, which is a part of a LazyColumn
item, is created based on the value of my mutable list for the index of that item. But on using debugger, it's clear that my Text
composable is not getting recomposed on change of value of mutable list. This is my code:
var listItemsOpen = remember { mutableListOf<Boolean>() }
listItemsOpen.clear()
for (i in 0..17){
listItemsOpen.add(i, false)
}
LazyColumn(Modifier
.constrainAs(listQuestions)
{
start.linkTo(glListQuestionsLeft)
end.linkTo(glListQuestionsRight)
top.linkTo(glListQuestionsTop)
bottom.linkTo(glListQuestionsBottom)
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
}
.alpha(if (isAnyCategoryClicked) 1f
else 0f))
{
itemsIndexed(if (txtToDisplay == "GENERAL") listGeneral
else if (txtToDisplay == "PRIVACY, SAFETY & SECURITY") listPrivacy
else if (txtToDisplay == "MY MONEY") listMyMoney
else if (txtToDisplay == "WITHDRAWAL") listWithdrawal
else listVoodleeAccSet
) { index, item ->
Column(
Modifier
.padding(
start = with(LocalDensity.current) { dimensionResource(id = R.dimen._9sdp) },
end = with(LocalDensity.current) { dimensionResource(id = R.dimen._9sdp) },
top = with(LocalDensity.current) { dimensionResource(id = R.dimen._12sdp) },
bottom = with(LocalDensity.current) { dimensionResource(id = R.dimen._12sdp) },
)
.clickable {
listItemsOpen[index] = !listItemsOpen[index]
if (listItemsOpen[index]) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
listItemsOpen.replaceAll { false }
}
listItemsOpen[index] = true
}
}
.fillMaxWidth()
.background(Color(0xFF000000))
)
{
Box(Modifier
.fillMaxWidth()
.padding(
start = with(LocalDensity.current) { dimensionResource(id = R.dimen._9sdp) },
end = with(LocalDensity.current) { dimensionResource(id = R.dimen._9sdp) },
top = with(LocalDensity.current) { dimensionResource(id = R.dimen._12sdp) },
bottom = with(LocalDensity.current) { dimensionResource(id = R.dimen._12sdp) },
)) {
Text(
text = if (txtToDisplay == "GENERAL") stringResource(id = R.string.general_que1)
else if (txtToDisplay == "PRIVACY, SAFETY & SECURITY") stringResource(
id = R.string.privacy_que1
)
else if (txtToDisplay == "MY MONEY") stringResource(id = R.string.my_money_que1)
else if (txtToDisplay == "WITHDRAWAL") stringResource(id = R.string.withdrawal_que1)
else stringResource(id = R.string.voodlee_acc_set_que1),
color = colorResource(id = R.color.bright_green),
fontSize = with(LocalDensity.current) {
dimensionResource(id = R.dimen._11ssp).toSp()
},
fontFamily = FontFamily(
Font(R.font.poppins_regular)
),
textAlign = TextAlign.Center,
modifier = Modifier.align(CenterStart)
)
Image(
painter = painterResource(id = R.drawable.ic_faq_dn),
modifier = Modifier
.align(CenterEnd)
.height(with(LocalDensity.current) { dimensionResource(id = R.dimen._22sdp) })
.width(with(LocalDensity.current) { dimensionResource(id = R.dimen._22sdp) }),
contentDescription = "ic down"
)
Image(
painter = painterResource(id = R.drawable.ic_faq_up),
modifier = Modifier
.align(CenterEnd)
.height(with(LocalDensity.current) { dimensionResource(id = R.dimen._22sdp) })
.width(with(LocalDensity.current) { dimensionResource(id = R.dimen._22sdp) }),
contentDescription = "ic up"
)
}
Spacer(modifier = Modifier.height(with(LocalDensity.current) {
dimensionResource(id = R.dimen._6sdp)
}))
**//BELOW TEXT COMPOSABLE IS NOT GETTING RECOMPOSED**
if (listItemsOpen[index]) {
Text(
text = if (txtToDisplay == "GENERAL") stringResource(id = R.string.general_ans1)
else if (txtToDisplay == "PRIVACY, SAFETY & SECURITY") stringResource(id = R.string.privacy_ans1)
else if (txtToDisplay == "MY MONEY") stringResource(id = R.string.my_money_ans1)
else if (txtToDisplay == "WITHDRAWAL") stringResource(id = R.string.withdrawal_ans1)
else stringResource(id = R.string.voodlee_acc_set_ans1),
color = colorResource(id = R.color.bright_green),
fontSize = with(LocalDensity.current) {
dimensionResource(id = R.dimen._11ssp).toSp()
},
fontFamily = FontFamily(
Font(R.font.poppins_light)
),
textAlign = TextAlign.Center,
)
}
}
}
}
How do I make the above Text
recompose when the value of mutable list for that index changes?
Upvotes: 3
Views: 1745
Reputation: 6863
Recompositions take place only on modification of state holders. The docs discourage the use of stuff like mutableListOf(...)
to store state in your app. You should instead use pre-defined state-holders.
Just change the declaration to
var listItemsOpen by remember { mutableStateOf(listOf<Boolean>()) }
The docs:-
_Caution: Using mutable objects such as ArrayList or mutableListOf() as state in Compose will cause your users to see incorrect or stale data in your app.
Mutable objects that are not observable, such as ArrayList or a mutable data class, cannot be observed by Compose to trigger recomposition when they change.
Instead of using non-observable mutable objects, we recommend you use an observable data holder such as State<List> and the immutable listOf()._
Upvotes: 2