【问题标题】:Recyclerview binds all views at the same timeRecyclerview 同时绑定所有视图
【发布时间】:2016-07-21 18:55:40
【问题描述】:

我在另一个回收站视图(LinearLayoutManager)中有一个垂直回收站视图(GridLayoutManager)。我现在面临的问题是,内部 recyclerview(使用 GridLayoutManager)同时绑定了它的所有项目,即使是目前不在屏幕上的视图(onBindViewHolder() 被调用它的所有项目)。

为了提供更多信息,在我的布局文件中,我将回收站视图的高度设置为wrap_content

我认为问题在于,由于有 2 个嵌套的垂直回收视图,当父 RV 想要测量其子级而子级是另一个 RV 时,在onMeasure() 它计算整个 RV 所需的大小,而不仅仅是它想在屏幕上绑定的部分。

知道如何解决这个问题吗?

这是我的外部 recyclerview 的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:id="@+id/component_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</FrameLayout>

这是我的内部 recyclerview 的代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/gutter"
android:paddingBottom="@dimen/gutter">

<TextView
    android:id="@+id/title_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/gutter"
    android:textSize="30sp"
    android:textColor="@android:color/white"
    android:fontFamily="sans-serif-thin"/>

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_slider"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

</LinearLayout>

P.S.:我将这个适配器委托用于我的外部 recyclerview: https://github.com/sockeqwe/AdapterDelegates

【问题讨论】:

  • 你说得对——回收站视图的长度是无限的,所以子 RV 会认为它适合刚刚找到的每个视图。我不会给出答案,因为我不能 100% 确定,但我认为您需要制作一个自定义布局管理器。

标签: android android-recyclerview gridlayoutmanager nestedrecyclerview


【解决方案1】:

我认为嵌套的 recyclerviews 是一个非常糟糕的主意。当我尝试滚动时,哪个 recyclerview 必须响应 scolling、parrent 或 child。

这就是我认为您正在寻找ExpandableListView 的原因?这仅限于两个级别的列表,但听起来它可以满足您的需求)。也解决了soling问题。

看起来像这样:

编辑:甚至嵌套的 ExpandableListViews 也是可能的:

编辑:检查this lib 的水平滚动

【讨论】:

  • 如果你有多个水平列表你如何处理这个?
  • 实际上在我的情况下是不同的,我不能在这里放任何设计截图,但基本上是外部 RV 中的一堆组件,其中一个组件可能是具有网格布局的 RV。所以我认为这不一定是一个坏主意,取决于你想做什么。由于我的设计,您的解决方案对我不起作用。
  • 你能添加一个小scetch吗?有油漆吗?
【解决方案2】:

这是一个已知的错误。
您不应将 RecyclerView 放在另一个 RecyclerView 中,因为 RecyclerView 为其子级提供了无限空间。
因此,内部 RecyclerView 一直在测量,直到数据集用完.
尝试在布局管理器上将 setAutoMeasureEnabled(false) 设置为 false,或者您可以通过使用包装适配器而不是内部回收器视图来解决此问题。

【讨论】:

  • 如果是已知错误,能否请您指出谷歌论坛中报告的错误?
  • 另外,我使用setAutoMeasureEnable(false);,问题是,从那时起,我必须自己测量它,我试图通过创建自己的 LayoutManager 来做到这一点,但我不知道如何正是为了正确创建我自己的布局管理器。
  • 我建议你改用包装适配器
  • 您能详细说明一下吗?你的意思是WrapperListAdapter
  • 你能在这里或github上发布一些代码吗?我会用你的代码解释
【解决方案3】:

您需要知道的第一件事是,当您嵌套滚动布局时,内部布局将获得无限的允许高度,从而有效地使它们成为 wrap_content。事实上,有一个相对简单的方法可以解决这个问题。 假设我有两个这样的嵌套 RecyclerView,在这种情况下是垂直方向的。

<RecyclerView 
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical>
    <View .../>
    <!-- other stuff -->
    <RecyclerView 
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"/>
</RecyclerView>

这里的内部 recyclerView 每次都会立即绑定它的所有子视图,因为从它的位置来看,您的屏幕将具有无限的高度。

解决方案是将内部 recyclerview 的高度设置为某个静态值,而不是 wrap_content 或匹配父级,因为其中任何一个都会简单地用一个视图填充外部 recyclerview高度。如果您使内部 recyclerview 的高度与显示的高度相同,您应该会看到问题消失了。

这是一个不会同时绑定所有子节点的实现:

<RecyclerView 
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical>
    <View .../>
    <!-- other stuff -->
    <RecyclerView 
         android:layout_width="match_parent"
         android:layout_height="@dimen/screen_height"
         android:orientation="vertical"/>
</RecyclerView>

请注意,内部 RecyclerView 的 layout_height 现在是从维度文件中提取的固定值。你自己必须想出一个合理的值才能放在那里。

旁注:为了使所有这些工作和滚动正常工作,您可能需要在 RecyclerViews 中使用参数:NestedScrollingEnabled - 您可能需要处理几个与此相关的已知错误大约。

即:innerRecyclerView.setHasFixedSize(true);innerRecyclerView.setNestedScrollingEnabled(false)

【讨论】:

  • 我之前试过,这个解决方案的问题是滚动不再起作用。我什至将嵌套滚动设置为 true,但我没有机会。
  • 您可能需要将内部 RecyclerView 的嵌套滚动设置为 false。试试innerRecyclerView.setHasFixedSize(true);innerRecyclerView.setNestedScrollingEnabled(false)
  • 如果 innerRecyclerView.setNestedScrollingEnabled(false); 我应该如何滚动浏览我在 RV 中的所有项目?在这种情况下,它只会显示我在 RV 中的一小部分物品。
  • 我猜你已经尝试了 setHasFixedSize(boolean) 和 setNestedScrollingEnabled(boolean) 的所有排列。你试过给你的内部回收视图一个最大高度吗?如果不是,我会尝试只这样做来解决您最初的问题,然后如果这不起作用,您能否在您的问题中提供一些代码来帮助我们解决这个问题?
  • 我很想看看你的 recyclerview 的 xml 以及你将内部 recyclerview 绑定到外部的任何地方。我将在今天的某个时候自己实现这个,我会尽力回复你。
【解决方案4】:

所以当您将滚动视图(由于包装内容而没有固定大小)放入另一个滚动视图(由于包装内容再次没有固定大小)时,会发生什么情况,两个嵌套滚动视图都无法呈现。

所以有两种解决方案--

1- 要么您必须考虑嵌套滚动视图的替代解决方案 2-您可以给外部recyclerview单元格固定高度,以便内部recyclerview可以获得一些固定的布局来呈现自己。

【讨论】:

  • #1) 没有其他选择,这是基于设计#2) 它不会起作用,因为如果我给它一个固定的高度,它就不会滚动
【解决方案5】:

我可以通过仅使用一个具有网格布局的 Recyclerview 来解决我的问题,并且基于我添加到其中的组件项,我为此更改了 spancount。基本上,我没有添加内部 recyclerview,而是将应该进入内部 recyclerview 的项目添加到外部 recyclerview。

【讨论】:

  • 这不是真正的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多