如何使RecyclerView顺利滚动?

时间:2015-07-06 15:04:14

标签: android android-recyclerview smooth-scrolling gridlayoutmanager

这更像是一个通用的问题,但经过大量的搜索和尝试后,我无法理解为什么这么难实现。 This是我能找到的最接近的答案,但仍无法实施。

具体来说我正在使用RecyclerView和GridLayoutManager。我想要的是平滑滚动的网格布局(如默认的gallary应用程序),没什么特别的,但是网格布局管理器的默认实现是在一个“生涩的”中滚动视图。方式。我尝试从上面的链接实现该方法,但没有成功。

我也试过实现LinearSmoothScroller,但我不确定如何实现computeScrollVectorForPosition方法。 computeScrollVectorForPosition上的Google's documentation字面上有0个字。

我找到了this 3 part tutorial,但它的帮助很小。所以,我想问的是:我们可以在LinearSmoothScroller中实现某种模板代码,还是扩展RecyclerView.SmoothScroller并实现平滑滚动?即使代码依赖于gridlayout中每行的项目数和项目数,也必须有一些方法可以轻松完成。我在这里错过了什么吗?

10 个答案:

答案 0 :(得分:31)

"生涩"的典型来源在Android中滚动是应用程序在更新UI的主应用程序线程上花费了太多时间。对于RecyclerView,这意味着在onBindViewHolder()或可能在onCreateViewHolder()中花费太多时间。每个都需要以亚毫秒的速度返回,这意味着您无法在其中执行磁盘I / O或网络I / O.

  认为我发现了问题。我正在使用holder.photo.setImageBitmap(BitmapFactory.decodeFile(itemList.get(position).get AbsolutePath())); onBindViewHolder()和图像文件大约100kb,列表中有大约十几个图像

是的,那将在主应用程序线程上进行磁盘I / O和图像解码。这将足够慢,导致UI中的jank(即"生涩"滚动)。

考虑使用图像加载库,如Picasso或Universal Image Loader,因为它们可以异步地从位图填充ImageView

This sample app使用通用图片加载器来帮助填充RecyclerView(带GridLayoutManager)的内容,数据源是设备上的可用视频。

答案 1 :(得分:30)

在您RecyclerViewActivity

中声明Fragment的任何地方添加此项
RecyclerView mRecyclerview = (RecyclerView) findViewById(...);
mRecyclerview.setNestedScrollingEnabled(false);
  

setNestedScrollview(false)为你做的工作。

答案 2 :(得分:11)

我刚遇到这个问题,并禁用嵌套滚动修复它。 这样做:

yourRecyclerview.setNestedScrollingEnabled(false);

或者您可以更改定义RecyclerView的xml文件中的值:

<android.support.v7.widget.RecyclerView
    android:id="@+id/yourRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:nestedScrollingEnabled="false"/>

答案 3 :(得分:2)

我刚遇到这个问题,我得到了 我将RecyclerView放在ScrollView中 因此,请切勿将RecyclerView放入可能引起问题的ScrollView内。

mLayoutManager.findFirstVisibleItemPosition()

那总是返回一个固定值。还要检查

recyclerview.setNestedScrollingEnabled(false);

答案 4 :(得分:1)

android:animateLayoutChanges="false"

答案 5 :(得分:1)

我通过覆盖calculateSpeedPerPixel(DisplayMetrics displayMetrics)方法使滚动变得平滑:

public class CustomLayoutManager extends LinearLayoutManager {

    protected CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private class CenterSmoothScroller extends LinearSmoothScroller {

        CenterSmoothScroller(Context context) {
            super(context);
        }

        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }

        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return 0.5f; //pass as per your requirement
        }
    }
}

答案 6 :(得分:0)

您需要使用“ Picasso”库异步加载图像,并使用fit()函数确保所加载图像的大小与布局中图像视图的大小相似。 。另外,如果您在滚动视图中使用回收站视图,请确保将nested scrolling设置为false。

我通过以上三种方法解决了问题

答案 7 :(得分:0)

使用库,如此处其他评论所述。还要确保您没有在Scrollview中嵌套Recyclerviews。这就是为什么我的以前不那么顺畅的原因之一。

答案 8 :(得分:0)

在里面花了 3 天后,我解决了项目中的平滑滚动问题。

问题在于 <layer-list> 文件的背景中设置了 item_user.xml drawable,因此需要 GPU 时间来渲染,这就是滚动不流畅的原因。

不要在适配器项中使用 <layer-list> 或任何其他复杂的 drawable。

答案 9 :(得分:-1)

只需添加此

animateLayoutChanges = true 

在recyclerview xml中