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.