最近碰到一个需求,记录一下。
一、需求
RecyclerView添加的FooterView也是一个RecyclerView,后者以二列的形式固定显示10条数据,每个item的高度不固定,如何正常显示? addFooterView()的时机为上面的数据已经加载完了,没有下一页的时候。
图示:
注意:上图中猜你喜欢部分正是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)
}
})
}
}