Manuel Lorenzo
08/23/2022, 1:41 PMChris Fillmore
08/23/2022, 4:04 PMManuel Lorenzo
08/23/2022, 4:10 PMclass MainViewModel(private val ioDispatcher: CoroutineDispatcher = <http://Dispatchers.IO|Dispatchers.IO>) : ViewModel() {
var documentList = emptyList<PDFDocument>().toMutableStateList()
....
fun toggleFavoriteDocument(pdfDocument: PDFDocument) {
documentList.find {
it == pdfDocument
}?.let {
it.favorite = !it.favorite
}
}
}
The composables are:
@Composable
fun DocumentRow(
document: PDFDocument,
onDocumentClicked: (String, Boolean) -> Unit,
onFavoriteValueChange: (Uri) -> Unit
) {
HeartIcon(
isFavorite = document.favorite,
onValueChanged = { onFavoriteValueChange(document.uri) }
)
}
@Composable
fun HeartIcon(
isFavorite: Boolean,
color: Color = Color(0xffE91E63),
onValueChanged: (Boolean) -> Unit
) {
IconToggleButton(
checked = isFavorite,
onCheckedChange = {
onValueChanged()
}
) {
Icon(
tint = color,
imageVector = if (isFavorite) {
Icons.Filled.Favorite
} else {
Icons.Default.FavoriteBorder
},
contentDescription = null
)
}
}
am I doing something wrong? because when I call the toggleFavouriteDocument
in the ViewModel
, I see it’s marked or unmarked as favourite but there is no recomposition at all anywhere (edited)Chris Fillmore
08/23/2022, 4:11 PMOleksandr Balan
08/23/2022, 4:18 PMfavorite
property in PDFDocument
baked by State
?Manuel Lorenzo
08/23/2022, 4:19 PMState
Oleksandr Balan
08/23/2022, 4:19 PMPDFDocument
class?Manuel Lorenzo
08/23/2022, 4:21 PM@Parcelize
data class PDFDocument(var uri: String, var favorite: Boolean): Parcelable()
Oleksandr Balan
08/23/2022, 4:28 PMState
properties. So I guess something like this should work:
@Parcelize
data class PDFDocument(val uri: String, val initialFavorite: Boolean): Parcelable {
var favorite by mutableStateOf(initialFavorite)
}
However I would recommend to make your models fully immutable:
@Parcelize
data class PDFDocument(val uri: String, val favorite: Boolean): Parcelable
And create a new ones (for example with a .copy()
) when the state changes:
fun toggleFavoriteDocument(pdfDocument: PDFDocument) {
documentList.replaceAll { if (it == pdfDocument) it.copy(favorite = !it.favorite) else it }
}
Albert Chang
08/23/2022, 4:35 PMManuel Lorenzo
08/23/2022, 4:56 PMfun toggleFavoriteDocument(pdfDocument: PDFDocument) {
documentList.find {
it == pdfDocument
}?.let {
it.copy(fav = !it.fav)
}.also {
_documentListLiveData.postValue(documentList)
}
}
and when I set a breakpoint in the last postValue
to see the content of the documentList
the documents are never favorite = true
nor fav = true
fun toggleFavoriteDocument(pdfDocument: PDFDocument) {
documentList.forEachIndexed { index, document ->
pdfDocument.takeIf {
document == pdfDocument
}?.let {
documentList[index] = document.copy(fav = !document.favorite)
}
}.also {
_documentListLiveData.postValue(documentList)
}
}
DocumentRow
and HeartIcon
?Oleksandr Balan
08/23/2022, 5:14 PMLiveData
, in this case something like this should work:
fun toggleFavoriteDocument(pdfDocument: PDFDocument) {
val newDocuments = _documentListLiveData.value?.map {
if (it == pdfDocument) {
it.copy(favorite = !it.favorite)
} else {
it
}
}
_documentListLiveData.postValue(newDocuments)
}
Why do you have a documentList
property then?Manuel Lorenzo
08/23/2022, 5:20 PM