32

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

具体来说,我将 RecyclerView 与 GridLayoutManager 一起使用。我想要的只是平滑滚动的网格布局(如默认的画廊应用程序),没有什么花哨的,但网格布局管理器的默认实现以“生涩”的方式滚动视图。我试图从上面的链接实现该方法,但没有成功。

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

我找到了这个 3 部分教程,但它的帮助很小。所以,我想问的是:是否有某种模板代码可以在 LinearSmoothScroller 中实现,或者通过扩展 RecyclerView.SmoothScroller 来实现平滑滚动?即使代码取决于网格布局中每行的项目数和项目数,也必须有一些方法可以轻松完成。我在这里错过了什么吗?

4

10 回答 10

45

RecyclerView在您声明的任何地方添加此ActivityFragment

RecyclerView mRecyclerview = (RecyclerView) findViewById(...);
mRecyclerview.setNestedScrollingEnabled(false);

setNestedScrollview(false)为你工作。

于 2017-04-15T04:06:37.120 回答
43

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

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

是的,这将在主应用程序线程上进行磁盘 I/O 和图像解码。这将慢到足以导致 UI 卡顿(即“生涩”滚动)。

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

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

于 2015-07-06T15:27:39.200 回答
17

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

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"/>
于 2018-02-13T10:46:07.943 回答
5

我刚遇到这个问题,我把它放进去RecyclerView所以ScrollView 请不要把它放在RecyclerView里面,ScrollView这也可能导致。

mLayoutManager.findFirstVisibleItemPosition()

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

recyclerview.setNestedScrollingEnabled(false);
于 2018-09-01T10:11:01.733 回答
4

我通过覆盖该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
        }
    }
}
于 2018-05-08T15:27:46.217 回答
1
android:animateLayoutChanges="false"
于 2016-10-19T15:24:21.140 回答
0

您需要使用“毕加索”库异步加载图像,并确保您加载的图像大小与布局中图像视图的大小相似,使用该fit()功能。此外,如果您在滚动视图中使用回收器视图,请确保设置nested scrolling为 false。

我使用上述三种方法解决了我的问题

于 2020-02-04T12:53:45.070 回答
0

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

于 2020-05-24T01:31:15.733 回答
0

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

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

不要<layer-list>在适配器项目中使用或任何其他复杂的可绘制对象。

于 2021-07-09T10:47:47.513 回答
-5

只需添加这个

animateLayoutChanges = true 

在回收站视图 xml

于 2016-08-22T13:13:29.197 回答