在android的Recycler View中实现间隔自动抛出



我在xml文件中有一个具有以下属性的回收器视图。
注意:对于这个回收者视图,我一次只在屏幕上显示一个项目。

<MyCustomRecyclerView
android:id="@+id/my_rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:orientation="horizontal"
android:overScrollMode="never"
android:paddingHorizontal="4dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> 

我使用PagerSnapHelper根据屏幕上视图的中心移动到左边或右边的位置。

val snapHelper = PagerSnapHelper()
snapHelper.attachToRecyclerView(this)

是工作正常的手动执行滚动操作。

现在,我想在一定的时间间隔(比如2.5秒)后添加一个自动滚动。我已经创建了一个处理程序,并发布了一个可运行的2.5秒的延迟。我试图调用fling(velocityX, velocityY)的RecyclerView与一个足够好的velocityX值

val scrollHandler = Handler()
val SCROLL_INTERVAL:Long = 2500           //scroll period in ms
val runnable = object : Runnable {
override fun run() {
//velocityX = 7500
fling(7500, 0)
scrollHandler.postDelayed(this, SCROLL_INTERVAL.toLong())
}
}

但是PagerSnaperHelper::findTargetSnapPosition()没有返回正确的目标位置,因为在手动滚动的情况下,视图实际上没有在屏幕上改变。这是返回元素的位置已经在屏幕上可见。

@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX,
int velocityY) {
final int itemCount = layoutManager.getItemCount();
if (itemCount == 0) {
return RecyclerView.NO_POSITION;
}
final OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
if (orientationHelper == null) {
return RecyclerView.NO_POSITION;
}
// A child that is exactly in the center is eligible for both before and after
View closestChildBeforeCenter = null;
int distanceBefore = Integer.MIN_VALUE;
View closestChildAfterCenter = null;
int distanceAfter = Integer.MAX_VALUE;
// Find the first view before the center, and the first view after the center
final int childCount = layoutManager.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = layoutManager.getChildAt(i);
if (child == null) {
continue;
}
final int distance = distanceToCenter(layoutManager, child, orientationHelper);
if (distance <= 0 && distance > distanceBefore) {
// Child is before the center and closer then the previous best
distanceBefore = distance;
closestChildBeforeCenter = child;
}
if (distance >= 0 && distance < distanceAfter) {
// Child is after the center and closer then the previous best
distanceAfter = distance;
closestChildAfterCenter = child;
}
}
// Return the position of the first child from the center, in the direction of the fling
final boolean forwardDirection = isForwardFling(layoutManager, velocityX, velocityY);
if (forwardDirection && closestChildAfterCenter != null) {
return layoutManager.getPosition(closestChildAfterCenter);
} else if (!forwardDirection && closestChildBeforeCenter != null) {
return layoutManager.getPosition(closestChildBeforeCenter);
}
// There is no child in the direction of the fling. Either it doesn't exist (start/end of
// the list), or it is not yet attached (very rare case when children are larger then the
// viewport). Extrapolate from the child that is visible to get the position of the view to
// snap to.
View visibleView = forwardDirection ? closestChildBeforeCenter : closestChildAfterCenter;
if (visibleView == null) {
return RecyclerView.NO_POSITION;
}
int visiblePosition = layoutManager.getPosition(visibleView);
int snapToPosition = visiblePosition
+ (isReverseLayout(layoutManager) == forwardDirection ? -1 : +1);
if (snapToPosition < 0 || snapToPosition >= itemCount) {
return RecyclerView.NO_POSITION;
}
return snapToPosition;
}

我想知道怎样才能达到我想要的结果?

我有一个变通办法来解决这个问题。在调用fling()之前,我调用scrollBy(x,y)来滚动项目,就好像它会在手动滚动期间发生一样。

val runnable = object : Runnable {
override fun run() {
scrollBy(400,0)
//velocityX = 7500
fling(7500, 0)
scrollHandler.postDelayed(this, SCROLL_INTERVAL.toLong())
}
}

最新更新