Open liyuhaolol opened 3 months ago
RecyclerView
的高度都会增加对应adapter的高度,这没问题。但是他内部的滑动范围却会成倍增加。也就是增加2个adapter的高度。这是这个问题触发的根本现象。contentAdapter
对应的高度无论如何都必须跟RecyclerView
的高度一致。再加上“Header”和"Footer"就会出现滑动高度是2倍增长的问题。contentAdapter
的对应高度不是应该一直跟他自己的内容实际高度保持一致才对么?为什么会强制跟RecyclerView
的高度一致呢?是特性,还是BUG?StateLayoutVH
里将宽高强制写为了MATCH_PARENT
。如图所示
WRAP_CONTENT
,所以想讨论是否有好的解决方案,能够兼容RecyclerView的MATCH_PARENT
和WRAP_CONTENT
这两种情况。我也会自己再试试,看能不能找到一个合适的解决方案。在setStateView
方法底下,判断stateView.layoutParams
为空的位置添加else分支,判断stateView的宽高设置,动态修改stateLayout的宽高属性,用来兼容RecyclerView
和占位View
的高度是包裹,不撑满空间的情况。
internal class StateLayoutVH(
parent: ViewGroup,
stateView: View?,
private val stateLayout: FrameLayout = FrameLayout(parent.context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
setStateView(this, stateView)
}
) : RecyclerView.ViewHolder(stateLayout), FullSpanAdapterType {
fun changeStateView(stateView: View?) {
setStateView(stateLayout, stateView)
}
companion object {
private fun setStateView(rootView: ViewGroup, stateView: View?) {
if (stateView == null) {
rootView.removeAllViews()
return
}
if (rootView.childCount == 1) {
val old = rootView.getChildAt(0)
if (old == stateView) {
// 如果是同一个view,不进行操作
return
}
}
stateView.parent.run {
if (this is ViewGroup) {
this.removeView(stateView)
}
}
if (stateView.layoutParams == null) {
stateView.layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT
).apply {
gravity = Gravity.CENTER
}
}else{
//判断stateView高度,如果不是MATCH_PARENT则把RootView的高度改为WRAP_CONTENT
if (stateView.layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT){
rootView.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
}else{
rootView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
}
//判断stateView宽度,如果不是MATCH_PARENT则把RootView的高度改为WRAP_CONTENT
if (stateView.layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT){
rootView.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
}else{
rootView.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
}
}
rootView.removeAllViews()
rootView.addView(stateView)
}
}
}
触发这个问题的需求是这样的,很简单。
RecyclerView
的高度是包裹,而不是撑满布局。使用的
占位View
高度同样包裹或者一个不大的高度值。本来想实现的效果是,无数据的时候,
ReclerView
底部不会存在大量空白高度。这时候关键点来了,我发现,当你使用
QuickAdapterHelper
调用addBeforeAdapter
添加Header
时,每添加一个BeforeAdapter
,ContentAdapter
对应内容区域的高度就会增加一个BeforeAdapter
的高度,直到撑满一个父布局。简单来说就是
ContentAdapter
对应内容区域会自动变高直到撑满他能撑满的布局高度。造成的问题,1,就算RecyclerView
的高度没有达到父布局高度,按照常理RecyclerView
应该是无法进行滑动的,但是因为ContentAdapter
对应内容区域的高度大于占位View
的高度,所以RecyclerView
竟然可以滑动。2,就算RecyclerView
高度达到了父布局高度,同样因为此时ContentAdapter
对应内容区域的高度也变成了父布局的高度,那么RecyclerView
下方会滑动出来大量的空白,说白了,这时候ContentAdapter
对应内容区域的高度已经不是占位View
的高度了,变成了HeaderView
总高度+占位View
的高度,直到占满父布局,我认为这是个BUG。ContentAdapter
对应内容区域的高度应该永远和要显示的占位View
高度保持一致不是么???只要不添加Header
,ContentAdapter
对应内容区域确实可以保证他跟占位View
的高度是一致的。但是只要添加了Header
,ContentAdapter
对应内容区域的高度就会开始变高,这真的不太对吧?使用的是4.1.4版本,可以用demo比较容易的重现此问题。如需要我可以上传github提供
![WechatIMG16](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/assets/16422963/28fb3efa-7bbc-4834-99a9-97a4861b0483)
就如上面2个图简单演示,
RecyclerView
内容高度本应该是图1的高度,实际也是,但是就像图2,它内部的滑动区域的高度却无端的高了一个Header
的高度。这真的就是个BUG吧?