我最近开始使用 Support Library v24
中提供的 SnapHelper
来获得一个漂亮的水平 RecyclerView
,就像在 < strong>Google Play 商店。
我的问题很简单。
通过使用 RecyclerView.OnScrollListener
我可以在滚动状态为稳定时收到通知(很像 ViewPager.OnPageChangedListener
。这是很重要,因为当滚动稳定时,我需要为将作为 LinearSnapHelper
的默认行为居中的 View 设置动画。该动画显示焦点被带到即将出现的-居中项目。
目前,我通过以下行设法获得了当滚动状态为空闲时居中的 View :
final int centered = (llm.findLastCompletelyVisibleItemPosition() - llm.findFirstCompletelyVisibleItemPosition()) / 2 + llm.findFirstVisibleItemPosition(); // where llm is my LinearLayoutManager
问题是,在滚动完成时启动动画很奇怪:我真的需要在滚动稳定时流畅地播放动画,这样当滚动空闲时,动画也会完成。
如您所见,我很难确定我的 RecyclerView
的哪一项将居中。
以下是我目前尝试过的解决方案。
当滚动状态设置为
RecyclerView.SCROLL_STATE_SETTLING
时,我尝试使用相同的计算。不幸的是,当滚动不空闲时从适配器调用findVisiblePosition
方法是一个坏主意:根据滚动速度,可见项目,当这些所谓的方法被调用时,可能不会卷轴完成时完全相同。事实上,它会告诉我在通话时哪些项目是可见的。这完全有道理,但我需要尝试找出答案...我尝试扩展
LinearSnapHelper
以便在调用onFling(...)
时我可以使用findSnapView(...)
获取将被捕捉 的 View 或使用findTargetSnapPosition(...)
希望告诉我哪个 View 在什么时候居中卷轴完成;我也尝试过,当滚动状态为
RecyclerView.SCROLL_STATE_SETTLING
时,使用findSnapView(...)
在所有这些解决方案中,没有一个通过多项测试(尝试使用不同的滑动强度和速度)。有些人在某些情况下做对了,但在不同情况下都做错了,因此导致解决方案无法使用。
查看 LinearSnapHelper
内部后,我想我开始明白,不知何故,在滑动之后,只要在滚动完成之前有必要,这个类就会多次计算总滚动和快照 View (滚动距离的量)因此知道哪个 View 将是最终快照 View ...除非我完全错了因为快照不居中?
无论如何,我的主要问题是:无论滑动的速度和力度如何,我如何知道滑动后我的 RecyclerView
的哪个项目将居中?
最佳答案
编辑:
正如一些人指出的那样,这是不可靠的,尤其是当卡扣是由于缓慢滑动而不是猛击而发生时。
我建议使用 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;
}
};
关于android - RecyclerView & SnapHelper -> 获取快照/目标 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40334241/