从我的一个问题的答案,我发现了一个允许项目重新排序的Google Demo of a ListView subclass。
该演示工作得很好,但我很难理解它是如何工作的:当一个项目被拖动到ListView的边界上方/下方时,ListView开始向上/向下滚动以显示新项目。必要的计算使用底层ScrollView的不同参数:
public boolean handleMobileCellScroll(Rect r) {
int offset = computeVerticalScrollOffset();
int height = getHeight();
int extent = computeVerticalScrollExtent();
int range = computeVerticalScrollRange();
int hoverViewTop = r.top;
int hoverHeight = r.height();
if (hoverViewTop <= 0 && offset > 0) {
smoothScrollBy(-mSmoothScrollAmountAtEdge, 0);
return true;
}
if (hoverViewTop + hoverHeight >= height && (offset + extent) < range) {
smoothScrollBy(mSmoothScrollAmountAtEdge, 0);
return true;
}
return false;
}
height
is是ListView本身的高度offset
是滚动位置=向上/向下滚动了多少单位/像素range
is是完整内容的高度。extent
- 嗯,这是什么?qazxsw poi从qazxsw poi继承了qazxsw poi并且文档说:
计算垂直滚动条拇指在水平范围内的垂直偏移。此值用于计算滚动条轨道内拇指的位置。
如果看一下qazxsw poi qazxsw poi不是由其中一个子类实现的,而是仅由ListView
直接实现:它只返回视图的高度。
这是有道理的:如果ListView / ScrollView的高度为500,那么一次可见的滚动内容部分也是500.这是ScrollExtent的含义吗?为什么ScrollExtent必要?为什么不直接使用getHeight()?
我想我错过了一些东西,我对任何暗示感到高兴!
这有点晚了,但希望没关系。
1)该方法实际上是由子类实现的。例如,computeVerticalScrollExtent()
就像View
(code的超类)一样。
2)computeVerticalScrollExtent()
的高度可以与其垂直卷轴的高度不同 - 想象一下带有奇怪的顶部/底部填充的View
。
这两点几乎使其他问题无关紧要:)
请注意,所有这些方法都可以根据其实现以不同的单位返回值,因此对于上面的示例,我使用索引,但在某些情况下,这些方法将返回等于项的宽度或高度的像素值。
特别是,如果启用了“平滑滚动条”功能,RecyclerView的LinearLayoutManager将返回索引,否则它将返回像素值。有关更多信息,请参阅支持库中的this。
补充阅读:AbsListView
这是一个示例代码,可以帮助您了解如何使用computeVerticalScrollExtent获取scrollBar的顶部和底部:
ListView
带有30个项目的ListView的scrollRange等于3000,这是由于scrollRange = numberOfItems * 100,因此scrollExtent = numberOfVisibleItems * 100和scrollOffset = numberOfScrolledItems * 100.您可以在AbsListView的源代码中找到这些单词的evidance