首页 > 解决方案 > 当用户将手从屏幕上移开时,如何使 Recycler View 滚动缓慢而流畅?

问题描述

这就是我快速滚动时的当前实现方式。

在此处输入图像描述

在第二个中,回收站视图中的所有项目都显示到最后。我想要实现的是如下所示的(现场演示:play store 中的回收站视图),

在此处输入图像描述

即使我们快速滚动,它也会显示 1 或 2 个项目,所以感觉很自然。我怎样才能使回收站视图以这种方式运行?

编码:

适配器

class CustomAdapter(private val mList: List<ItemsViewModel>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.card_view_design, parent, false)

        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

    }

    override fun getItemCount(): Int {
        return mList.size
    }

    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
        val imageView: ImageView = itemView.findViewById(R.id.imageview)
        val textView: TextView = itemView.findViewById(R.id.textView)
    }
}

执行

val recyclerview = findViewById<RecyclerView>(R.id.recyclerview)
recyclerview.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
val data = ArrayList<ItemsViewModel>()
val adapter = CustomAdapter(data)
recyclerview.adapter = adapter

标签: androidkotlinandroid-layoutandroid-recyclerviewuser-experience

解决方案


当 aRecyclerView水平滚动时,scrollHorizontallyBy()会调用 dx 值多次,根据手指的 fling (push) 值,可以使滚动表现得平滑和真实。

vertical 也一样RecyclerViewscrollVerticallyBy()用不同的 dy 值调用。

因此,您可以操纵此dx值以获得所需的行为;在您的情况下,您需要获得较小的dx.

您会想到一个固定dx值,但这不会那么自然;相反,您可以将其除以固定数量以缩小相同的 dx 值。

在这里,我使用了一个任意值,您可以根据需要对其进行操作。

因此,您需要在使用水平 recyclerView时使用自定义LinearLayoutManager& 覆盖 :scrollHorizontallyBy()

class MyLinearLayoutManager(context: Context?, orientation: Int, reverseLayout: Boolean) :
    LinearLayoutManager(context, orientation, reverseLayout) {

    override fun scrollHorizontallyBy(
        dx: Int,
        recycler: RecyclerView.Recycler?,
        state: RecyclerView.State?
    ): Int {
        var newDx = (dx / 1.2).toInt() // 1.2 is an arbitrary value 
        if (newDx == 0 && dx != 0) { // To have no 0 values (Optionally)
            newDx = 1
        }
        
        return super.scrollHorizontallyBy(newDx, recycler, state)
    }

}

推荐阅读