美文网首页android技术Android开发Android技术知识
解决paging3配合GridLayoutManager时foo

解决paging3配合GridLayoutManager时foo

作者: 支离破碎_SuperLee | 来源:发表于2021-05-16 02:56 被阅读0次

    使用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能够独占一行了。

    相关文章

      网友评论

        本文标题:解决paging3配合GridLayoutManager时foo

        本文链接:https://www.haomeiwen.com/subject/ttjljltx.html