微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 ConcatAdapter 中恢复嵌套 recyclerview 的滚动状态

如何解决在 ConcatAdapter 中恢复嵌套 recyclerview 的滚动状态

我正在使用新的 ConcatAdapter 和 Android 导航组件来创建一个复杂的 recyclerView,其中包含嵌套的水平滚动列表。我正在尝试恢复这些嵌套列表在旋转、导航等方面的状态。我已经阅读了关于该主题this 文章,但我正在努力研究如何在这种情况下恢复状态。>

当我将上面文章中的 adapter.stateRestorationPolicy = PREVENT_WHEN_EMPTY 应用到包含嵌套 recyclerview 的适配器时,它不起作用。我尝试在收到数据时更新嵌套适配器,并尝试在数据接收时将它们添加到 concat 适配器,但没有成功。

我的片段

override fun onViewCreated(view: View,savedInstanceState: Bundle?) { 
   
    val concatAdapter = ConcatAdapter()

    binding.recyclerView.apply {
        adapter = concatAdapter
        layoutManager = linearlayoutmanager(requireContext())
    }

    viewmodel.data.observe(viewLifecycleOwner,{ listItems ->
        concatAdapter.addAdapter(nestedlistadapter(listItems))
    })
}

也试过这个:

override fun onViewCreated(view: View,savedInstanceState: Bundle?) { 
    val nestedlistadapter = nestedlistadapter()
    val concatAdapter = ConcatAdapter(nestedlistadapter)

    binding.recyclerView.apply {
        adapter = concatAdapter
        layoutManager = linearlayoutmanager(requireContext())
    }

    viewmodel.movies.observe(viewLifecycleOwner,{ items ->
        nestedlistadapter.clearItems()
        nestedlistadapter.addItems(items)
        nestedlistadapter.notifyItemRangeChanged(0,items.size)
    })
}

我还尝试延迟将适配器绑定到外部 recyclerview:

 override fun onViewCreated(view: View,savedInstanceState: Bundle?) { 
    lateinit var concatAdapter: ConcatAdapter()

    binding.recyclerView.apply {
        layoutManager = linearlayoutmanager(requireContext())
    }

    viewmodel.movies.observe(viewLifecycleOwner,{ items ->

        concatAdapter = ConcatAdapter(MoviehorizontallistAdapter(it.data.toMutableList()))

        if (binding.recyclerView.adapter != concatAdapter) {
            binding.recyclerView.adapter = concatAdapter
        }

    })
}

我的嵌套 Recyclerview 适配器

class nestedlistadapter(
     private val listItems: MutableList<Movie> = mutablelistof()
) : RecyclerView.Adapter<nestedlistadapter.ViewHolder>() {
private val scrollStates: MutableMap<String,Parcelable?> = mutableMapOf()
private val viewPool = RecyclerView.RecycledViewPool()

init {
    // this does not do anything,(it's also added in the Movielistadapter)
    stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
}

private fun getSectionID(position: Int): String {
    return listItems.getorNull(position)?.id?.toString().orEmpty()
}

override fun onViewRecycled(holder: ViewHolder) {
    super.onViewRecycled(holder)

    val key = getSectionID(holder.layoutPosition)
    scrollStates[key] = holder.rv.layoutManager?.onSaveInstanceState()
}

override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewHolder {
    val binding = nestedlistadapterBinding.inflate(
        LayoutInflater.from(parent.context),parent,false
    )

    return ViewHolder(binding)
}

override fun getItemCount(): Int = if (listItems.isEmpty()) 0 else 1

override fun onBindViewHolder(holder: ViewHolder,position: Int) {
    holder.bind(listItems)
}

inner class ViewHolder(
    binding: nestedlistadapterBinding
) : RecyclerView.ViewHolder(binding.root) {
    val rv = binding.recyclerView

    fun bind(listItems: List<Movie>) {
        val lm = linearlayoutmanager(rv.context,HORIZONTAL,false)
        lm.initialPrefetchItemCount = 4

        rv.apply {
            setRecycledViewPool(viewPool)
            layoutManager = lm
            adapter = Movielistadapter(listItems)
        }

        restoreState()
    }

    // This is to restore the state when recycling items (not rotation)
    private fun restoreState() {
        val key = getSectionID(layoutPosition)
        val state = scrollStates[key]
        if (state != null) {
            rv.layoutManager?.onRestoreInstanceState(state)
        } else {
            val padding = rv.resources.getDimension(R.dimen.default_padding).toInt()
            rv.addItemdecoration(horizontallistMargindecoration(padding))
            rv.layoutManager?.scrollToPosition(0)
        }
    }
}

感谢任何帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。