scrollBy在嵌套的recyclerview中无法正常工作

我有一个垂直滚动RecyclerView水平滚动内部RecyclerViews就像这样。

EXPL

通过这个实现,用户可以同步滚动每个水平的回收站。 但是,当用户垂直滚动到父回收站视图时,刚刚附加在窗口上的新水平回收站不会显示在同一个滚动x位置上。 这个是正常的。 因为它刚刚创build。

所以,我试图在显示之前滚动到滚动的位置。 像这样:

注意 :这是父级回收站的方向是垂直的适配器。

  @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); CellColumnViewHolder viewHolder = (CellColumnViewHolder) holder; if (m_nXPosition != 0) { // this doesn't work properly viewHolder.m_jRecyclerView.scrollBy(m_nXPosition, 0); } } 

在这里输入图像说明

正如你所看到的, scrollBy不会影响第10行第11行第12 第13行。之后,我debugging了代码,以便能够找出发生了什么事情。 当我使用scrollBy设置滚动位置时,childCount()对于第10 第11 第12 第13 返回零,因此它们不滚动。 但为什么 ? 为什么其他人工作?

  • 我怎样才能解决这个问题 ?
  • 是onViewAttachedToWindow正确的地方滚动新的附加recyclervViews?

注意 :我也testing了scrollToPosition() ,它没有像这样的问题。 但我不能用在我的情况。 因为用户可以滚动到可能不是确切位置的任何x位置。 所以我需要使用x值而不是位置设置滚动位置。

编辑 :你可以查看源代码

Solutions Collecting From Web of "scrollBy在嵌套的recyclerview中无法正常工作"

我find了一个使用scrollToPositionWithOffset方法代替使用scrollBy的解决scheme。 即使两个人都滚动到另一个位置,他们在背后的工作过程也是完全不同的。

例如:如果您尝试使用scrollBy滚动任何像素位置,并且您的recyclerView没有设置任何适配器,这意味着没有任何数据要显示,因此它还没有任何项目,那么scrollBy不起作用。 RecyclerView使用其layoutManager的scrollBy方法。 所以在我的情况下,我使用LinearLayoutManager水平recyclerViews。

让我们看看它在做什么:

 int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || dy == 0) { return 0; } mLayoutState.mRecycle = true; ensureLayoutState(); final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDy = Math.abs(dy); updateLayoutState(layoutDirection, absDy, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { if (DEBUG) { Log.d(TAG, "Don't have any more elements to scroll"); } return 0; } final int scrolled = absDy > consumed ? layoutDirection * consumed : dy; mOrientationHelper.offsetChildren(-scrolled); if (DEBUG) { Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled); } mLayoutState.mLastScrollDelta = scrolled; return scrolled; } 

正如你可以看到scrollBy忽略滚动的意图,如果当时没有任何孩子。

  if (getChildCount() == 0 || dy == 0) { return 0; } 

另一方面,即使没有任何设置的数据, scrollToPosition也可以很好地工作。

根据Pro RecyclerView幻灯片 ,下面的示例完美地工作。 但是你不能用scrollBy来做到这一点。

 void onCreate(SavedInstanceState state) { .... mRecyclerView.scrollToPosition(selectedPosition); mRecyclerView.setAdapter(myAdapter); } 

因此 ,我改变了一些使用scrollToPositionWithOffset()东西。

在这个实现之前,我正在计算精确的scroll x位置作为一个像素。

之后,当滚动进入空闲状态时,计算scrollToPositionWithOffset()的第一个参数的第一个完整的可见位置。

对于第二个参数是偏移量,我得到的值使用view.getLeft()函数,这有助于得到这个视图相对于其父母的左侧位置。

在这里输入图像说明

它完美的作品!