SwipeRefreshLayout 停止工作/RecyclerView 不一致地触发 SwipeRefreshLayout
SwipeRefreshLayout stops working / RecyclerView inconsistently triggers 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);
在View
中,计算canScrollVertically(-1)
的代码取决于computeVerticalScrollOffset
、computeVerticalScrollRange
和computeVerticalScrollExtent
的结果。
RecyclerView
依赖于 LinearLayoutManager
来进行这些计算。如果 smoothScrollbarEnabled
是 true
(默认值),这会转发给 ScrollbarHelper
做一些近似,以显示花哨的滚动条。
如果您 RecyclerView
中的项目大小不同,这些近似值将是完全错误的。
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setSmoothScrollbarEnabled(false);
recyclerView.setLayoutManager(llm);
解决了我们的问题,让 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);
在View
中,计算canScrollVertically(-1)
的代码取决于computeVerticalScrollOffset
、computeVerticalScrollRange
和computeVerticalScrollExtent
的结果。
RecyclerView
依赖于 LinearLayoutManager
来进行这些计算。如果 smoothScrollbarEnabled
是 true
(默认值),这会转发给 ScrollbarHelper
做一些近似,以显示花哨的滚动条。
如果您 RecyclerView
中的项目大小不同,这些近似值将是完全错误的。
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setSmoothScrollbarEnabled(false);
recyclerView.setLayoutManager(llm);
解决了我们的问题,让 SwipeRefreshLayout
每次到达列表顶部时都能可靠地触发。