解决paging3配合GridLayoutManager时footer不能占一行的问题

使用paging3开发时,官方demo只有包含LinearLayout的部分代码,
当我们需要配合GridLayoutManager(spanCount=2)时,
发现footer不能适配占满一行,而是单独占了一个spanSize。


n0QoE.png

我们知道,GridLayoutManager可以通过设置spanSizeLookup来达到某些Item填充多个spanSize的目的
如下:

 spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return if(position == itemCount-1) spanCount else 1
            }
        }

但是使用paging3和ConcatAdapter配合时,footer并不会一直在最下方展示,
因为LoadStateAdapter 会根据paging的加载状态动态添加及删除footerAdapter,
所以position的最后一行不一定是footer,
源码如下:

abstract class LoadStateAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() {
    var loadState: LoadState = LoadState.NotLoading(endOfPaginationReached = false)
            set(loadState) {
                if (field != loadState) {
                    val oldItem = displayLoadStateAsItem(field)
                    val newItem = displayLoadStateAsItem(loadState)

                    if (oldItem && !newItem) {
                        notifyItemRemoved(0)
                    } else if (newItem && !oldItem) {
                        notifyItemInserted(0)
                    } else if (oldItem && newItem) {
                        notifyItemChanged(0)
                    }
                    field = loadState
            }
        }
}

此时我们只能通过ConcatAdapter查询itemViewType来处理spanSizeLookup ,
需要先创建footer

        //创建footer和empty
        val footer = FooterAdapter(adapter)
        ...
        ...
        //ConcatAdapter.Config.Builder().setIsolateViewTypes(false).build() 是重点,否则拿不到需要的itemviewtype
        val concatAdapter = ConcatAdapter(ConcatAdapter.Config.Builder().setIsolateViewTypes(false).build(),adapter, footer)
//记得重写LoadStateAdapter中的getItemType方法
    override fun getStateViewType(loadState: LoadState): Int {
        return VIEW_TYPE
    }

通过如上代码可以创建ConcatAdapter,
然后重写spanSizeLookup

              GridLayoutManager(
                    requireContext(),
                    2,
                    GridLayoutManager.VERTICAL,
                    false
                ).apply {
                    spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                        override fun getSpanSize(position: Int): Int {
                            return if (concatAdapter
                                    ?.getItemViewType(position) in arrayOf(
                                    BaseEmptyAdapter.VIEW_TYPE,
                                    BasePlaceholderAdapter.VIEW_TYPE,
                                    FooterAdapter.VIEW_TYPE
                                )
                            ) spanCount else 1
                        }
                    }
                }

通过以上设置,即可完成paging3与GridLayoutManager的联动,并且保证footer能够独占一行了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容