You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android RecyclerView(GridLayoutManager)smoothScrollTo()滚动速度调整问题

Fix Smooth Scrolling to Bottom for RecyclerView with GridLayoutManager

I’ve run into this exact issue before—using smoothScrollToPosition() with GridLayoutManager often skips the smooth animation and jumps straight to the last item, which is super frustrating. The solutions you found for LinearLayoutManager don’t translate directly, but here are two tested fixes that work for Grid layouts:

Method 1: Custom LinearSmoothScroller

The default smooth scroller for GridLayoutManager doesn’t handle direction or speed correctly. By creating a custom scroller, you can enforce proper smooth scrolling behavior:

import android.content.Context
import android.graphics.PointF
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller

class GridSmoothScroller(context: Context) : LinearSmoothScroller(context) {
    override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
        val layoutManager = layoutManager as? GridLayoutManager ?: return super.computeScrollVectorForPosition(targetPosition)
        val firstVisibleItem = layoutManager.findFirstVisibleItemPosition()
        // Determine scroll direction (down if target is below first visible item)
        val scrollDirection = if (targetPosition > firstVisibleItem) 1 else -1
        return PointF(0f, scrollDirection.toFloat())
    }

    override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
        // Adjust this value to control scroll speed: higher = slower
        return 200f / (displayMetrics?.densityDpi ?: 160)
    }

    override fun getVerticalSnapPreference(): Int {
        // Snap to the bottom of the target item for consistent behavior
        return SNAP_TO_END
    }
}

To use this scroller instead of the default:

val gridLayoutManager = recyclerView.layoutManager as GridLayoutManager
val smoothScroller = GridSmoothScroller(recyclerView.context)
smoothScroller.targetPosition = adapter.itemCount - 1
gridLayoutManager.startSmoothScroll(smoothScroller)

This method overrides how the scroller calculates direction and speed, ensuring smooth vertical scrolling regardless of grid column count.

Method 2: Manual Smooth Scroll with ValueAnimator

If you need more control over the animation (like custom duration), you can manually animate the scroll using ValueAnimator:

import android.animation.ValueAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView

fun smoothScrollToBottom(recyclerView: RecyclerView, layoutManager: GridLayoutManager) {
    val totalItems = recyclerView.adapter?.itemCount ?: 0
    if (totalItems <= 0) return

    val targetPosition = totalItems - 1
    val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()

    // If already near the bottom, use default smooth scroll
    if (lastVisiblePosition >= targetPosition - 3) {
        recyclerView.smoothScrollToPosition(targetPosition)
        return
    }

    // Check if target view is already laid out
    val targetView = layoutManager.findViewByPosition(targetPosition)
    targetView?.let {
        val totalScrollDistance = it.bottom - recyclerView.height + recyclerView.paddingBottom
        ValueAnimator.ofInt(0, totalScrollDistance).apply {
            duration = 800 // Adjust animation length here (ms)
            addUpdateListener { animator ->
                val currentScroll = animator.animatedValue as Int
                recyclerView.scrollBy(0, currentScroll - recyclerView.scrollY)
            }
            start()
        }
    } ?: run {
        // Target view isn't loaded yet—scroll close first, then smooth scroll
        recyclerView.scrollToPosition(targetPosition - 5)
        recyclerView.post {
            smoothScrollToBottom(recyclerView, layoutManager)
        }
    }
}

Call this function whenever you need to scroll to the bottom:

smoothScrollToBottom(recyclerView, gridLayoutManager)

This approach calculates the exact distance needed to scroll and animates it incrementally, avoiding the jumpy behavior of the default method.

Both methods work reliably for GridLayoutManager—pick the one that fits your use case best!

内容的提问来源于stack exchange,提问作者Mo Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:40:08