将水平 RecyclerView 作为项目放置在垂直 RecyclerView 中时的自动滚动问题

Posted

技术标签:

【中文标题】将水平 RecyclerView 作为项目放置在垂直 RecyclerView 中时的自动滚动问题【英文标题】:Autoscroll issue when horizontal RecyclerView is placed as an item in a vertical RecyclerView 【发布时间】:2017-02-07 16:09:08 【问题描述】:

为了重现这个问题,我克隆了一个existing project 并添加了两个片段。所以现在有一个 Activity 和一个 ViewPager 有 2 个片段。每个Fragment 都有一个RecyclerView(垂直),其中包含多个RecyclerView(水平)。

现在的问题是当中点水平RecyclerView 留在顶部时,切换选项卡上垂直RecyclerView 的自动滚动。

例如:

    第1页滚动到这个位置

(注意第一个 H-Recycler 视图被设置为只有一半可见)

    然后在 tablayout 上点击 PAGE 2 以转到第 2 页。

    现在再次点击 tablayout 上的 PAGE 1 以返回到第 1 页。这里预期的滚动位置是我们之前离开的位置,但它会自动滚动到顶部位置。像这样

(第一个 RecyclerView 完全可见,而不是一半。)


我在寻找解决方案时得到了一些线索。

v24.1.1 和 v24.2.1(撰写本文时最新)的库会出现此问题,但当它降级到 v23.4.0 时,它会按预期工作。因此很明显,库中的某些内容被修改导致了这种行为。 在包含 webview 的项目中遇到了同样的问题。 webView 和 H-recyclerView 之间的共同点是两者都可以在内部水平滚动。问题可能与滚动事件的消耗有关。

【问题讨论】:

你是在调用 pageVisible 事件还是什么? 否...当用户可见提示发生更改时,不会调用任何内容。 嗨@HBB20 你有解决这个问题的办法吗?? 当时降级到版本 23.4.0 是可行的。您使用的版本号是多少? 【参考方案1】:

ViewPagerFragment切换时可以保存滚动状态。让我们在 Activity 中添加一个 static 变量,它将像这样存储滚动状态

public static int scrollPositionIndex;
public static int scrollPositionOffset;

现在从您的Fragment 覆盖setUserVisibleHint 函数。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) 
    super.setUserVisibleHint(isVisibleToUser);
    // Make sure that we are currently visible
    if (this.isVisible()) 
        // If we are becoming invisible, then...
        if (!isVisibleToUser) 

            // Save scroll state
            LinearLayoutManager layoutManager = ((LinearLayoutManager) mRecyclerView.getLayoutManager());
            YourActivity.scrollPositionIndex = layoutManager.findFirstVisibleItemPosition();

            View v = mRecyclerView.getChildAt(0);
            YourActivity.scrollPositionOffset = (v == null) ? 0 : (v.getTop() - mRecyclerView.getPaddingTop());

         else 
            // Scroll to the saved position
            mLayoutManager.scrollToPositionWithOffset(YourActivity.scrollPositionIndex,
                    YourActivity.scrollPositionOffset);

            // Reset the value
            YourActivity.scrollPositionIndex = 0;
            YourActivity.scrollPositionOffset = 0;
        
    

【讨论】:

感谢您的回复。我尝试了您的解决方案,但仍然表现相同......它会自动滚动...... 您在这里遇到什么问题? setUserVisibleHint 是否被调用?可以保存滚动的位置吗? 所以你需要检查scrollPositionIndexscrollPositionOffset是否有任何价值。检查您是否也在使用正确的LayoutManager 滚动。 我对其进行了调试并确认已收到值但行为保持不变...为了解决此问题,目前我已将库版本设置为 v23.4.0 并且它按预期运行。

以上是关于将水平 RecyclerView 作为项目放置在垂直 RecyclerView 中时的自动滚动问题的主要内容,如果未能解决你的问题,请参考以下文章

将RecyclerView项目更改为高于所有其他项目

如何将 textView 放置在 recyclerView 上方?

如何同步容器内动态水平滚动视图的滚动视图位置?

如何解决单击水平 RecyclerView 中的项目的问题?

创建具有水平和垂直滚动的 RecyclerView

如何使用垂直 GridLayoutManager 水平居中 RecyclerView 项目