[英]Android Jetpack compose - Observe a live data not trigger after second channge
我正在使用 viewModel 將數據傳遞給我的撰寫視圖。 問題是我想通過在 viewModel 中的模型中歸檔來處理展開和折疊視圖。 因此,如果某些 UI 單擊 expand 方法,我將調用 viewModel 和 doExpand 方法,如下所示:
private val _acquiredCoupons = MutableLiveData<List<AcquiredCoupon>>(listOf())
val acquiredCoupons: LiveData<List<AcquiredCoupon>> = _acquiredCoupons
fun doExpand(coupon : AcquiredCoupon){
val index = _acquiredCoupons.value?.indexOf(coupon) ?: -1
val newItems = _acquiredCoupons.value?.toMutableList().also {
it?.get(index)?.isExpanded = true
}
_acquiredCoupons.value = newItems
Timber.i("Mahdi $index")
}
但問題是在撰寫 UI 中更新模型后不會觸發並且不會發生重新撰寫! 我正在觀察這樣的實時數據:
val items = viewModel.acquiredCoupons.observeAsState(initial = emptyList())
在您的觀察代碼中,您需要使用observeAsState
,因此您的視圖將使用更改該值的任何 LiveData 更新重新組合。
val items by viewModel.acquiredCoupons.observeAsState()
問題很可能是您將原始值傳遞給Composable
(請在有機會時在您的問題中包含示例代碼段)。 如果認為該值等於前一個值,則不會發生重組。
解決此問題的一種方法是將State
對象本身傳遞給目標Composable
。
例如,如果您是這樣設置的:
@Composable
fun CouponBar(
coupons: List<Coupon>
) { ... }
然后嘗試
@Composable
fun CouponBar(
coupons: State<List<Coupon>>
) { ... }
如果有人在觀察列表時仍然遇到此問題,我發現一個很好的解決方案是在 ViewModel/LiveData 中從List
切換到SnapshotStateList 。
從這個轉換后:
class MainViewModel : ViewModel() {
val itemLiveData: LiveData<List<String>>
get() = items
private val items = MutableLiveData<List<String>>()
private val itemImpl = mutableListOf<String>()
fun addItem(name: String){
itemImpl.add(name)
items.postValue(itemImpl)
}
}
對於這種形式:
class MainViewModel : ViewModel() {
val itemLiveData: LiveData<SnapshotStateList<String>>
get() = items
private val items = MutableLiveData<SnapshotStateList<String>>()
private val itemImpl = mutableStateListOf<String>()
fun addItem(name: String){
itemImpl.add(name)
items.postValue(itemImpl)
}
}
當項目添加到列表中時,我的組合按預期工作
@Composable
fun ItemList(model: MainViewModel = viewModel()) {
Column {
Button(
onClick = { model.addItem("New item") },
content = { Text(text="Add item") }
)
val items by model.itemLiveData.observeAsState()
if( items.isNullOrEmpty() ) {
Text(text = "No items")
}
else {
items?.forEach { item ->
Text(text=item)
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.