scrollBy在嵌套的recyclerview

时间:2017-06-29 08:09:02

标签: android scroll android-recyclerview

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

expl

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

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

注意:这是父级Recyclerview的适配器,其方向是垂直的。

 @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);
        }
    }

enter image description here

如您所见,scrollBy第10行第11行第12行第13行之后,我调试了代码,以便找出发生了什么。当我使用scrollBy设置滚动位置时,childCount()为第10行第11行第12行第13行<返回零/ strong>所以他们不滚动。但为什么 ?为什么其他人工作?

  • 如何解决此问题?
  • onViewAttachedToWindow是否正确滚动新附加的recyclervViews?

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

修改:您可以查看The source code

1 个答案:

答案 0 :(得分:4)

我发现使用scrollToPositionWithOffset方法的解决方案使用scrollBy。即使两个都滚动到另一个位置,它们在背面也有不同的工作过程。

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

让我们看看它在做什么:

LinearLayoutManager

正如您所见,如果当时没有任何孩子,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; } 即使没有任何设定数据也可以完美地工作。

根据Pro RecyclerView slide,下面的示例效果很好。但是你不能用scrollBy做到这一点。

scrollToPosition

结果,我改变了使用void onCreate(SavedInstanceState state) { .... mRecyclerView.scrollToPosition(selectedPosition); mRecyclerView.setAdapter(myAdapter); } 的小事。

在此实现之前,我正在计算精确的滚动x位置作为像素。

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

对于第二个参数,它是偏移量,我使用scrollToPositionWithOffset()函数获取值,这有助于获得此视图相对于其父级的左侧位置。

enter image description here

它完美无缺!!