How implement sticky footer in recyclerview

后端 未结 8 1766
时光说笑
时光说笑 2021-02-04 02:52

I have RecyclerView and I need next behavior:

  • if there are a lot of items (more then fits screen) - footer is last item
  • if few item/no item - footer is lo
相关标签:
8条回答
  • 2021-02-04 03:29
    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)
    }
    }
    
    0 讨论(0)
  • 2021-02-04 03:38

    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.

    0 讨论(0)
提交回复
热议问题