使用 AdapterDelegates 更新嵌套 RecyclerView 中的对象

问题描述 投票:0回答:0

我正在尝试为嵌套列表实现一个类似的系统。我使用 AdapterDelegates、MVVM、StateFlow。 屏幕看起来像这样: https://i.imgur.com/VqqM9fP.png

数据来自api,在视图中Models被扔进StateFlow:

class HomeViewModel @Inject constructor(private val repository: Repository,) : ViewModel() {

    private val _data = MutableStateFlow<List<HomeScreen>>(emptyList())
    val data = _data.asStateFlow()

    init {createHomeScreen()}

    private fun createHomeScreen() {
        viewModelScope.launch(Dispatchers.IO) {
            _data.value = repository.getItems()
        }
    }
...
}

进一步在片段中,整个东西都放入适配器中:

class HomeFragment : Fragment {
 private val adapter by lazy {HomeAdapter { clickableView, item ->onItemClick(clickableView, item)}}

 viewLifecycleOwner.lifecycleScope.launch {
            viewModel.data.collect{ data ->
                adapter.items = data
            }
        }

private fun onItemClick(clickableView: ClickableView, item: Item) {
        viewModel.onItemClick(clickableView, item)
    }
}

外部适配器:

class HomeAdapter(onItemClick: (ClickableView, Item) -> Unit) :
    AsyncListDifferDelegationAdapter<HomeScreen>(HomeScreenDiffUtil()) {

    init {
        delegatesManager
            .addDelegate(horizontalGridDelegate(onItemClick))
    }
}

它的代表:


fun horizontalGridDelegate(onItemClick: (ClickableView, Item) -> Unit) =
    adapterDelegateViewBinding<HorizontalGrid, HomeScreen, ItemContainerViewHolderBinding>({ inflater, root ->
        ItemContainerViewHolderBinding.inflate(inflater, root, false)
    }) {
        bind {
            binding.bind(item){clickableView, item ->
                clickableView.listPosition = bindingAdapterPosition
                onItemClick(clickableView, item) }
        }
    }

fun ItemContainerViewHolderBinding.bind(
    item: HomeScreen,
    onItemClick: (ClickableView, Item) -> Unit
) {
    val dogAdapter = OneListItemAdapter(onItemClick)
    recyclerView.adapter = dogAdapter
    dogAdapter.items = item.list
    ...
    )
}

内部适配器及其代表:

class OneListItemAdapter(onItemClick: (ClickableView, Item) -> Unit) :
    AsyncListDifferDelegationAdapter<Item>(ItemDiffUtil()) {

    init {
        delegatesManager
            .addDelegate(dogsDelegate(onItemClick))
    }
}

fun dogsDelegate(onItemClick: (ClickableView, Item) -> Unit) =
    adapterDelegateViewBinding<Dog, Item, DogViewHolderBinding>({ inflater, root ->
        DogViewHolderBinding.inflate(inflater, root, false)
    }) {
        binding.btnFavorite.setOnClickListener {
            /**need this click*/
            ClickableView.FAVORITE.itemPosition = bindingAdapterPosition
            onItemClick(ClickableView.FAVORITE, item)
        }
        bind {
            binding.btnFavorite.isSelected = item.isFavorite
        }
    }

问题本质:

您不能只将选择器设置为在单击时触发,因为对服务器的请求可能无法通过。因此,您需要以某种方式在流程中胜任地发出它。到目前为止,我已经尝试这样做:

... ViewModel() {
private fun addToFavorites(item: Dog, itemPosition: Int, listPosition: Int) {
        viewModelScope.launch(Dispatchers.IO) {
            val newData = _data.value.toMutableList()
            val newList = newData[listPosition].list.toMutableList() as MutableList<Dog>
            newList[itemPosition] =
                newList[itemPosition].copy(isFavorite = !newList[itemPosition].isFavorite)
            newData[listPosition] = (newData[listPosition] as HorizontalGrid).copy(list = newList)
            _data.value = newData
        }
    }
}

但是通过这个实现,我也更新了整个内部回收器。 也许来自 DiffUtil 的有效负载会帮助我。但是我没有足够的知识,包括 Kotlin,无法实现它们。或者也许还有其他方法?我已经浏览了很多关于委托的信息,但我还没有在任何地方遇到对象重绘。我知道在这种情况下你完全可以不用委托,但目标是使用这个特定的库。提前谢谢你

android kotlin mvvm android-recyclerview nestedrecyclerview
© www.soinside.com 2019 - 2024. All rights reserved.