我正在使用snaphelper使用recyclerview。 这是我的recyclerview:
final LinearLayoutManager lm = new LinearLayoutManager(getContext(),
LinearLayoutManager.HORIZONTAL, false);
recyclerview.setLayoutManager(lm);
final PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerview);
当用户滚动到另一个单元格时,我需要对新单元格位置执行某些操作。
这就是我要做的事情:
recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
return;
}
if recyclerview == null) {
return;
}
//recyclerview.clearOnChildAttachStateChangeListeners();
int firstVisible = ((LinearLayoutManager) viewerRv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
if (firstVisible == RecyclerView.NO_POSITION) {
return;
}
doSomething(firstVisible);
}
问题是firstVisible var并不总是给我正确的位置,例如当我从位置0滚动到9时,这可以是输出: 0,1,2,3,4,4,5,9
还有另一种方法可以获得正确的当前位置吗?
最佳做法是什么?
答案 0 :(得分:3)
这是我的解决方案:
recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
final int offset = topRv.computeHorizontalScrollOffset();
if (offset % myCellWidth == 0) {
final int position = offset / myCellWidth ;
}
}
});
随时给我当前的位置。
答案 1 :(得分:1)
onScrollStateChanged(int state)的文档说明:
SCROLL_STATE_IDLE:没有滚动。
SCROLL_STATE_DRAGGING:用户在屏幕上拖动手指(或者以编程方式完成。
SCROLL_STATE_SETTLING:用户抬起手指,动画现在正在放慢速度。
当状态为SCROLL_STATE_DRAGGING或SCROLL_STATE_SETTLING时,您获得位置,显然这将返回回收器视图已滚动的所有位置。如果你想获得当前位置,你应该在recyclerview停止时获取(newState = SCROLL_STATE_IDLE)
您可以使用与此类似的代码来控制滚动的开始和结束:
boolean hasStarted = (state == SCROLL_STATE_DRAGGING);
boolean hasEnded = (state == SCROLL_STATE_IDLE);
所以最终的代码可能是这样的:
//Initialize this variable on class that initialize recyclerview
private boolean hasStarted;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//Scroll is not start and user is dragging his finger
if(!hasStarted && newState == SCROLL_STATE_DRAGGING){
hasStarted = true;
}
//If scroll starts and it finish
if(hasStarted && newState == SCROLL_STATE_IDLE){
//Restart variable for next iteration
hasStarted = false;
//Do something
doSomething(firstVisible);
}
}
答案 2 :(得分:0)
在你的适配器中应该有一个名为
的方法Max
谢谢, 阿南德
答案 3 :(得分:0)
val recyclerView: RecyclerView = findViewById(R.id.myPagerRecyclerView)
val snapHelper: SnapHelper = PagerSnapHelper()
snapHelper.atttachToRecyclerView(snapHelper)
recyclerView.addOnScrollListener(SnapOnScrollListener(snapHelper, NOTIFY_ON_SCROLL) { position ->
// Do what you want
}
class SnapOnScrollListener(
private val snapHelper: SnapHelper,
var behavior: Int = NOTIFY_ON_SCROLL,
var onSnapPositionChangeListener: ((position: Int) -> Unit)? = null
) : RecyclerView.OnScrollListener() {
private var snapPosition = RecyclerView.NO_POSITION
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (behavior == NOTIFY_ON_SCROLL) {
dispatchSnapPositionChange(recyclerView)
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (behavior == NOTIFY_ON_SCROLL_STATE_IDLE
&& newState == RecyclerView.SCROLL_STATE_IDLE) {
dispatchSnapPositionChange(recyclerView)
}
}
private fun dispatchSnapPositionChange(recyclerView: RecyclerView) {
val layoutManager = recyclerView.layoutManager ?: return
val snapView = snapHelper.findSnapView(layoutManager) ?: return
val snapPosition = layoutManager.getPosition(snapView)
val snapPositionChanged = this.snapPosition != snapPosition
if (snapPositionChanged) {
onSnapPositionChangeListener?.invoke(snapPosition)
this.snapPosition = snapPosition
}
}
companion object {
const val NOTIFY_ON_SCROLL = 0
const val NOTIFY_ON_SCROLL_STATE_IDLE = 1
}
}
Detecting snap changes with Android’s RecyclerView SnapHelper by Christian Fregnam