答案为时已晚,但也许这会对某人有所帮助。
我在同样的问题上苦苦挣扎,找不到可接受的解决方案。
通过以下方式解决:
1)首先,您需要从 RecyclerView 覆盖 onMeasure 以保存最大元素高度:
class CustomRecycleView(ctx: Context, attrs: AttributeSet) : RecyclerView(ctx, attrs) {
private var biggestHeight: Int = 0
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
for (i in 0 until childCount) {
val child = getChildAt(i)
child.measure(widthSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
val h = child.measuredHeight
if (h > biggestHeight) biggestHeight = h
}
super.onMeasure(widthSpec, MeasureSpec.makeMeasureSpec(biggestHeight, MeasureSpec.EXACTLY))
}
}
2)在你的layput中用这个CustomRecycleView替换RecycleView:
<CustomRecycleView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
当列表中的新元素可见时调用 onMeasure,如果该元素最高,则保存该值。例如:如果第一个元素的高度最低,但lates 的高度最高,则在开始时 RecycleView 将与第一个元素的高度匹配,但滚动后它将保持与最高元素的匹配。如果您不需要在开始时使 RecycleView 高度与最高项目匹配,那么您可以在此处停止。
3)要在开始时执行此操作,您必须进行 hack(基于@MidasLefko 的建议):要初步了解最高元素的高度,您需要在末尾和开头添加滚动机制。我这样做如下:
private fun initRecycleView(items: ArrayList<Object>) {
val adapter = Adapter()
rv.visibility = View.INVISIBLE
rv.vadapter = adapter
rv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
rv.setHasFixedSize(true)
rv.smoothScrollToPosition(pinnedPosts.size)
Handler().postDelayed({
rv.smoothScrollToPosition(0)
}, 300)
Handler().postDelayed({
rv.visibility = View.VISIBLE
}, 700)
}
将回收视图的可见性设置为不可见,并在 700 毫秒后设置为可见,以使此过程对用户不可见。此外,滚动开始的延迟为 300 毫秒,因为如果没有延迟,它可能无法正常工作。就我而言,这对于 3 个元素的列表是必需的,而这些延迟对我来说是最佳的。
还要记得去掉 onStop() 中的所有 Handler 回调