I have RecyclerView and I need next behavior:
class FooterViewHolder(private val parent: ViewGroup) {
...
fun bind(item: Item) {
...
itemView.post(::adjustTop)
}
private fun adjustTop() {
val parent = parent as RecyclerView
var topOffset = parent.height
for (child in parent.children) topOffset -= child.height
(itemView.layoutParams as ViewGroup.MarginLayoutParams)
.setMargins(0, topOffset.coerceAtLeast(0), 0, 0)
}
}
The selected answer is flawed. I already commented on it and explained why so. You may want to read that if your interested.
So if the selected answer is wrong, whats a different better way to solve this?
1) Create you layout like so:
<ConsraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<-- This is your footer and it can be anything you want -->
<TextView
android:id="@+id/yourFooter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</ConstraintLayout>
2) Set the height of your footer as bottomPadding of your RecyclerView
. It is crucial to do on preDraw
so you can have the proper height or size of yur footer.
view.doOnPreDraw {
val footerheight = yourFooter.height
recyclerView.updatePadding(bottom = footerHeight)
...
}
3) Now all you need to do is to listen to recyclerview scroll and listen when you need to translate you footer at the correct time. So do something like:
view.doOnPreDraw {
val footerheight = yourFooter.height
recyclerView.updatePadding(bottom = footerHeight)
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val range = recyclerView.computeVerticalScrollRange()
val extent = recyclerView.computeVerticalScrollExtent()
val offset = recyclerView.computeVerticalScrollOffset()
val threshHold = range - footerHeight
val currentScroll = extent + offset
val excess = currentScroll - threshHold
yourFooter.transalationX = if (excess > 0)
footerHeight * (excess.toFloat()/footerHeight.toFloat()) else 0F
}
})
}
Hope this would be helpful to someone in the future.