简体   繁体   English

删除某些项目后,LazyColumn 项目保持在同一位置

[英]LazyColumn items stay in same position after some items removed

I have LazyColumn with swipe-to-delete.我有带滑动删除功能的 LazyColumn。 When I swipe an item, it is deleted by viewModel.当我滑动一个项目时,它会被 viewModel 删除。 The problem is that if I swipe the item away, the LazyColumn doesn't update the position of other items (as shown in GIF).问题是,如果我将项目滑开,LazyColumn 不会更新其他项目的位置(如 GIF 所示)。

在此处输入图像描述

Here's my code implementation:这是我的代码实现:

@ExperimentalMaterialApi
@Composable
fun Screen() {
    val livedata = viewModel.itemsLiveData.observeAsState()
    val stateList = remember { mutableStateListOf<Data>() }

    stateList.addAll(livedata.value!!)
    SwipableLazyColumn(stateList)
}

@ExperimentalMaterialApi
@Composable
fun SwipableLazyColumn(
    stateList: SnapshotStateList<Data>
) {
    LazyColumn {
        items(items = stateList) { item ->
            val dismissState = rememberDismissState()
            if (dismissState.isDismissed(EndToStart) || dismissState.isDismissed(StartToEnd)) {
                viewModel.swipeToDelete(item)
            }
            SwipeToDismiss(
                state = dismissState,
                directions = setOf(StartToEnd, EndToStart),
                dismissThresholds = {
                    FractionalThreshold(0.25f)
                },
                background = {},
                dismissContent = {
                    MyData(item)
                }
            )
        }
    }
}

I use SnapshotStateList as it's suggested here .我按照此处的建议使用SnapshotStateList Although I don't use swapList because it clears out all items虽然我不使用swapList因为它会清除所有项目

ViewModel :视图模型

    class MyViewModel @Inject internal constructor(
    private val itemRepository: ItemRepository
) : BaseViewModel(), LifecycleObserver {

    private val itemsList = mutableListOf<MyData>()

    private val _itemsLiveData = MutableLiveData<List<MyData>>()
    val itemsLiveData: LiveData<List<MyData>> = _itemsLiveData

    init {
        loadItems()
    }

    private fun loadItems() {
        viewModelScope.launch {
            itemRepository.getItems().collect {
                when (it) {
                    is Result.Success -> onItemsLoaded(it.data)
                    is Result.Error -> {
                        onItemsLoaded(emptyList())
                    }
                }
            }
        }
    }

    private fun onItemsLoaded(itemsList: List<MyData>) {
        itemsList.clear()
        itemsList.addAll(notifications)

        _itemsLiveData.value = if (itemsList.isNotEmpty()) {
            itemsList
        } else {
            null
        }
    }

    fun swipeToDelete(item: MyData) {
        if (itemsList.size == 0) return
        viewModelScope.launch {
            when (
                val result =
                    itemRepository.deletelItem(item)
            ) {
                is Result.Success -> {
                    onItemDeleted(item)
                }
                is Result.Error -> {
                    showSnackBar(
                        "error"
                    )
                }
            }
        }
    }

    private fun onItemDeleted(item: MyData) {
        itemsList.remove(item)
        _itemsLiveData.value = itemsList
    }
}

You need to provide key for the LazyColumn 's items .您需要为LazyColumnitems提供key

By default, each item's state is keyed against the position of the item in the list.默认情况下,每个项目的 state 与列表中项目的 position 键控。 However, this can cause issues if the data set changes, since items which change position effectively lose any remembered state.但是,如果数据集更改,这可能会导致问题,因为更改 position 的项目实际上会丢失任何记住的 state。

Example例子

LazyColumn {
    items(
        items = stateList,
        key = { _, listItem ->
            listItem.hashCode()
        },
    ) { item ->
        // As it is ...
    }
}

Reference 参考

You should refresh your list inside viemodel(delete item) and return modified list right here您应该在 viemodel 中刷新列表(删除项目)并在此处返回修改后的列表

var tempList = itemList
ItemList.clear() 
ItemList.addAll(tempList)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM