在NestedScrollView中包含RecyclerView会为所有项目调用onBindView [英] Having RecyclerView inside a NestedScrollView calls onBindView for all the items
问题描述
我在LinearLayout
中垂直放置了两个RecyclerViews
.我需要使它们都可滚动,这就是为什么要将LinearLayout
放在NestedScrollView
I have two RecyclerViews
placed vertically in a LinearLayout
. I need to make both of them scrollable and that is why I have put the LinearLayout
inside NestedScrollView
这是我的布局文件.
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/featured_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="@+id/all_topic_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
此外,我正在禁用Java代码中的嵌套滚动.
Also, I am disabling nested scrolling in Java code.
disableNestedScrolling(findViewById(R.id.all_topic_list));
disableNestedScrolling(findViewById(R.id.featured_list));
我的RecylerView
库版本是26.1.0
My RecylerView
library version is 26.1.0
这可以很好地工作,但是随后会为列表中的所有项目调用onBindViewHolder
方法.理想情况下,只应为列表中的可见项调用它.
This works fine perfectly, but then onBindViewHolder
method is getting called for all the items in the list. Ideally it should only be called for the visible items in the list.
我认为问题正在发生,因为我将wrap_content
给予RecyclerView
.关于此问题的很多答案表明问题是在v23.2.1中已解决,但我已经在使用v26.1.0.如何解决这个问题?
I think the issue is happening because I am giving wrap_content
to the RecyclerView
. A lot of answers on this question suggest that the issue is solved in v23.2.1, but I am already using v26.1.0. How to solve this issue?
推荐答案
我遇到了完全相同的问题. RecyclerViews
并不意味着以相同的滚动方向放置在滚动容器内.仅当高度设置为MATCH_PARENT
时,视图回收才有效.
I had exactly the same problem. RecyclerViews
are not meant to be placed inside scroll containers with the same scroll direction. The view recycling only works when the height is set to MATCH_PARENT
.
取决于NestedScrollView
内部内容的复杂性和RecyclerView
项目的预期数量:
Depending on the complexity of the content inside of the NestedScrollView
and the anticipated amount of RecyclerView
items:
-
忽略该问题.如果只有几个简单的项目,您可以 完全不需要视图回收.
Ignore the problem. If there are only a few simple items, you may not need view recycling at all.
遇到问题时,我分析了其他流行应用程序的布局:例如,WhatsApp在其应用程序的某些部分仅使用RecyclerViews
(或ListViews
具有视图回收功能).
When I hit the problem, I analysed the layouts of other popular apps: For example, WhatsApp only uses RecyclerViews
(or ListViews
with view recycling) in some parts of their app.
尤其是这个包含数百个可能项目的组设置屏幕由ScrollView
包裹的多个ListViews
组成,没有任何视图回收.
Particularly, this group settings screen with hundreds of possible items is made of multiple ListViews
wrapped by a ScrollView
, without any view recycling.
将NestedScrollView
替换为一个
ReyclerView
具有多个项目类型,并全部放入其中的可滚动内容.如果您需要视图回收,这就是方法.
Replace the NestedScrollView
with a single
ReyclerView
with multiple item types and put all of your scrollable content inside of it. This is the way to go if you need view recycling.
请注意,还必须将NestedScrollView
中的所有其他内容(页眉和页脚,间距)转换为具有自己的ViewHolders
的RecyclerView
项.
Beware that you also have to convert all the other content in the NestedScrollView
(headers and footers, spacing) to RecyclerView
items with their own ViewHolders
.
如果设置非常简单,则建议您按照上面的链接在没有其他库的情况下实现它.
If the setup is rather simple, I would recommend you to implement it without additional libraries, following the link above.
可以使用几种不同的库来解决您的问题(所有库都遵循第二种方法,只用一个RecyclerView
),但是大多数库都具有许多您可能不需要的额外功能:
There are a few different libraries available to solve your problem (all of them follow the second approach with a single RecyclerView
), but most come with a lot of extra features which you may not need:
它带有 ViewRenderer
/ViewModel
接口,就像
单个项目类型的部分" RecyclerView.您将创建一个
每种商品类型,然后将它们注册在单个适配器中.
It comes with a ViewRenderer
/ViewModel
interface, which works like a
"partial" RecyclerView for a single item type. You would create one
for every item type and then register them in a single adapter.
airbnb创建的库/框架,并在其应用程序中大量使用. 他们有很多可滚动的内容(类似于网页), 很多不同的项目类型.环氧树脂也有助于 页面上的不同项目,当 内容或其顺序更改.如果只需要一个屏幕,就太多了.
A library/framework create by airbnb and used heavily in their app. They have a lot of scrollable content (similar to a web page) with a lot of different item types. Epoxy also helps with the composition of the different items on a page, and it handles animations when the content or its order changes. Too much if you only need it for a single screen.
Facebook创建的完整UI框架,它带有自己的呈现引擎,XML布局的替代品等等.据我了解,它允许您处理大量项目(例如Facebook时间轴),并且视图回收是自动处理的.像Epoxy一样,只有在您的应用程序包含无休止滚动以及许多不同项目类型之类的东西并且您确实需要性能的情况下,才使用此功能.
A complete UI framework created by Facebook which comes with it's own rendering engine, a replacement for xml layouts and much more. As far as I understand, it allows you to do to handle large amounts of items (like the Facebook timeline) and the view recycling is handled automatically. Like Epoxy, you would only use this if your app includes things like endless scrolling with a lot of different item types and you really need the performance.
我尝试了Epoxy和RendererRecyclerViewAdapter,但是毕竟我创建了自己的多项目类型适配器.可以用不到100行的代码来创建它.
I tried Epoxy and RendererRecyclerViewAdapter, but after all I created my own multiple item type adapter. It can be created in less than 100 lines of code.
这篇关于在NestedScrollView中包含RecyclerView会为所有项目调用onBindView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!