我最近开始使用SnapHelper
中提供的Support Library v24
,以便与 Google Play商店中的水平RecyclerView
非常相似。< / p>
我的问题很简单。
使用RecyclerView.OnScrollListener
我可以在滚动状态为设置时收到通知(非常类似于ViewPager.OnPageChangedListener
。这很重要,因为当滚动定居时,我需要为LinearSnapHelper
的默认行为居中的视图设置动画。该动画显示焦点将转移到即将成为焦点的项目。
现在,我设法通过以下行获得滚动状态空闲时居中的视图:
final int centered = (llm.findLastCompletelyVisibleItemPosition() - llm.findFirstCompletelyVisibleItemPosition()) / 2 + llm.findFirstVisibleItemPosition(); // where llm is my LinearLayoutManager
问题是,当滚动完成时启动动画很奇怪:当滚动停止时我真的需要平滑地播放动画,这样当滚动空闲时,动画也会完成。
正如您所看到的,我很难找到RecyclerView
中哪一项将是居中的。
以下是我到目前为止尝试的解决方案。
当滚动状态设置为RecyclerView.SCROLL_STATE_SETTLING
时,我尝试使用相同的计算。不幸的是,当滚动不空闲时从适配器调用findVisiblePosition
方法是一个坏主意:根据滚动速度,当调用这些所谓的方法时,可见项可能不完全相同滚动完成时。实际上它会告诉我在通话时哪些物品是可见的。这完全有道理,但我需要尝试找出它......
我尝试扩展 LinearSnapHelper
,以便在调用onFling(...)
时我可以使用findSnapView(...)
来获取 snapped 或使用findTargetSnapPosition(...)
希望在滚动完成时告诉我哪个视图居中;
当滚动状态为RecyclerView.SCROLL_STATE_SETTLING
时,我也尝试使用findSnapView(...)
在所有这些解决方案中,没有一个通过多次测试(尝试不同的滑动强度和速度)。有些人在一些情况下做对了,但在不同情况下弄错了,因此解决方案无法使用。
查看LinearSnapHelper
内部我认为我开始明白,不知何故,在滑动之后,此类会在滚动完成之前根据需要多次计算总滚动并捕捉视图(距离的数量)滚动)因此知道哪个视图将是最终捕捉视图 ...除非我把它弄错了因为snapped不居中?
无论如何,我的主要问题是:无论速度和力度如何,我怎样才能知道我的RecyclerView
哪个项目会在刷卡后居中?
答案 0 :(得分:5)
编辑:
正如少数人所指出的那样,这是不可靠的,特别是当快速滑动而不是甩尾时发生快照时。
我建议您使用RecyclerView.OnScrollListener
,并在RecyclerView
'已确定'后检查位置。这里有一个很好的教程
上一个回答:
您需要继承SnapHelper
并覆盖findTargetSnapPosition
。由super.findTargetSnapPosition(layoutManager, velocityX, velocityY)
计算的位置是您RecyclerView
即将捕捉到的位置。
SnapHelper snapHelper = new LinearSnapHelper() {
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
int snapPosition = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);
// Do something with snapPosition
return snapPosition;
}
};
答案 1 :(得分:0)
如果您使用LinearSnapHelper
,则有LinearSnapHelper#findTargetSnapPosition
方法。它返回要捕捉的视图的适配器位置。
答案 2 :(得分:0)
滚动结算后,您可以使用layoutManager.findFirstCompletelyVisibleItemPosition()
。
答案 3 :(得分:0)
我有一个水平的 Recycler View ,看看 layoutManager :
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, true)
val snapHelper: SnapHelper = PagerSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)
您可以使用 findLastCompletelyVisibleItemPosition 来查找位置
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visiblePosition = layoutManager.findLastCompletelyVisibleItemPosition()
if (visiblePosition >= 0) {
//do somthing with item position
}
}
})