如何使RecyclerView顺利滚动?

roc*_*ght 24 android smooth-scrolling gridlayoutmanager android-recyclerview

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

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

我也尝试实现LinearSmoothScroller,但我不确定如何实现computeScrollVectorForPosition方法.关于computeScrollVectorForPosition的Google文档字面上有0个字.

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

Com*_*are 34

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

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

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

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

此示例应用程序使用Universal Image Loader来帮助填充RecyclerView(with GridLayoutManager)的内容,数据源是设备上的可用视频.


Ahm*_*aza 33

RecyclerView在你Activity或你的声明中的任何地方添加它Fragment

RecyclerView mRecyclerview = (RecyclerView) findViewById(...);
mRecyclerview.setNestedScrollingEnabled(false);
Run Code Online (Sandbox Code Playgroud)

setNestedScrollview(false) 为你工作.


小智 11

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

yourRecyclerview.setNestedScrollingEnabled(false);
Run Code Online (Sandbox Code Playgroud)

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

<android.support.v7.widget.RecyclerView
    android:id="@+id/yourRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:nestedScrollingEnabled="false"/>
Run Code Online (Sandbox Code Playgroud)


SKP*_*SKP 5

我通过覆盖该方法使滚动平滑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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我只是遇到这个问题,我得到了我把RecyclerViewScrollView 所以请永远把RecyclerView里面的ScrollView还可能会导致。

mLayoutManager.findFirstVisibleItemPosition()
Run Code Online (Sandbox Code Playgroud)

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

recyclerview.setNestedScrollingEnabled(false);
Run Code Online (Sandbox Code Playgroud)