Android add的footerView是RecyclerView

169 阅读2分钟

最近碰到一个需求,记录一下。

一、需求

RecyclerView添加的FooterView也是一个RecyclerView,后者以二列的形式固定显示10条数据,每个item的高度不固定,如何正常显示? addFooterView()的时机为上面的数据已经加载完了,没有下一页的时候

图示:

image.png

注意:上图中猜你喜欢部分正是add的FooterView,猜你喜欢的部分的View不是开始预留出的高度,上面的的RecyclerView是铺满全屏的

二、问题

如果footView的RecyclerView的高度是wrap_content,不会显示任何内容;如果给一个固定高度比如300dp,那么就只会显示300dp的内容,如何得到footView的RecyclerView内容的真实高度?一开始思路局限于布局等原因,会浪费很多时间。

三、思路

给footView的RecyclerView一个很大的高度,这个高度足够显示10条猜你喜欢的内容,然后计算RecyclerView每个item的View的高度,计算出左边和右边显示的item的高度的和,以高的那边作为最终footView的RecyclerView的高度,记得加条目上间距。

四、代码

footView的RecyclerView的一些基本设置

val topBottomGap = 10   //条目上下的间隙,单位dp
val leftRightGap = 10   //条目左右的间隙,单位dp
//布局管理器
val staggeredGridLayoutManager =
    StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
staggeredGridLayoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE
//RecyclerView设置一些参数
mRecyclerView.run {
    layoutManager = staggeredGridLayoutManager
    itemAnimator?.changeDuration = 0
    isNestedScrollingEnabled = false
    addItemDecoration(
        StaggeredGridModelItemDecoration(  //自定义的间隙类
            leftRightGap,
            topBottomGap,
            false
        )
    )
    adapter = mRecommendAdapter
}

具体的计算的代码

/**
 * 添加猜你喜欢的View
 */
private fun addLikeFooterView() {
    //有数据才添加FootView
    if (mList.isNotEmpty()) {
        //addFooterView
        mAdapter.addFooterView(mFootView)
        //计算RecyclerView子View的高度,然后修改layoutParams为正确的高度
        val viewTreeObserver = mRecyclerView.viewTreeObserver
        viewTreeObserver.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                //获取child的数量
                val childCount = mRecyclerView.childCount
                var oddTotalHeight = 0  //奇数项高度和
                var evenTotalHeight = 0   //偶数项高度和
                for (i in 0 until childCount) {
                    if (i % 2 == 0) {
                        evenTotalHeight += mRecyclerView.getChildAt(i).height
                    } else {
                        oddTotalHeight += mRecyclerView.getChildAt(i).height
                    }
                }
                //修改高度
                val layoutParams = mRecyclerView.layoutParams
                layoutParams.height = if (evenTotalHeight > oddTotalHeight) {
                    evenTotalHeight + 4*topBottomGap.dp2px.toInt()  //2列左右5个条目4个间隙
                } else {
                    oddTotalHeight + 4*topBottomGap.dp2px.toInt()   //2列左右5个条目4个间隙
                }
                layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
                mRecyclerView.layoutParams = layoutParams
                mRecyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }
}

个人学习笔记