SwipeRefreshLayout停止工作/ RecyclerView不一致触发SwipeRefreshLayout

时间:2017-05-25 09:13:29

标签: android android-recyclerview android-support-library swiperefreshlayout

我发现RecyclerView在Nexus 6P API 25 7.1.1模拟器上不一致地激活SwipeRefreshLayout存在问题。 我们使用支持库的最新版本:

compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1'

我有一个带有数据集的RecyclerView,该数据集在发生拉动时会被添加到前面(将项目添加到顶部),它在我的布局中声明如下:

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefresh"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" />
</android.support.v4.widget.SwipeRefreshLayout>

我能够触发手势大约2-3次,将项目添加到RecyclerView但是它不再允许我触发拉动刷新。我们从不调用SwipeRefreshLayout.setEnabled(false)。似乎RecyclerView在内部对canScrollVertically(-1)的响应是真的,即使我们位于项目列表的顶部。

我们处理的唯一有趣的事情是我们覆盖RecyclerView的布局管理器让我们滚动到底部:

LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setStackFromEnd(true); // Start with most recent messages (enables scroll-to-bottom)
recyclerView.setLayoutManager(llm);

1 个答案:

答案 0 :(得分:0)

View中,计算canScrollVertically(-1)的代码取决于computeVerticalScrollOffsetcomputeVerticalScrollRangecomputeVerticalScrollExtent的结果。

RecyclerView依靠LinearLayoutManager来进行这些计算。如果ScrollbarHelpersmoothScrollbarEnabled(默认值),则会转发到true进行一些近似,以显示花式滚动条。

如果RecyclerView中的项目大小不同,这些近似值将完全错误。

LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setSmoothScrollbarEnabled(false);
recyclerView.setLayoutManager(llm);

解决了我们的问题,每当我们到达列表顶部时,SwipeRefreshLayout就会可靠地触发。