NestedScrollView中的RecyclerView导致RecyclerView膨胀所有元素 [英] RecyclerView inside NestedScrollView causes RecyclerView to inflate all elements
问题描述
将RecyclerView放在NestedScrollView内时遇到问题,这会导致呈现RecyclerView适配器的所有元素.
I'm having an issue with placing a RecyclerView inside a NestedScrollView, which causes ALL elements of the RecyclerView's adapter to be rendered.
这是一个相当大的问题,因为RecyclerView显示的列表可能包含数百个元素.
This is a rather large issue, as the lists that the RecyclerView is showing can contain several hundred elements.
此刻(很显然)会造成很大的延迟,因为它必须立即渲染所有视图,并且不能像RecyclerView正常使用那样重用任何已经膨胀的视图.
This is at the moment causing quite a lot of lag (obviously) as it has to render all views at once, and can't reuse any already inflated views as the RecyclerView normally does.
这是我当前的XML(已删除了一些膨胀以将其最小化):
This is my current XML (Removed some bloat to minimize it):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="90dp">
<!-- Some content -->
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Some more content -->
</LinearLayout>
<!-- Product list -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
这是我的Fragment中的onCreateView(),它使包含NestedScrollView和RecyclerView的视图膨胀:
This is my onCreateView() from the Fragment that is inflating the view containing the NestedScrollView and RecyclerView:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.category_content_fragment, container, false);
ButterKnife.bind(this, root);
List<Product> products = new ArrayList<>(); //This is populated by other means, not relevant to the issue
productsRecyclerView.setNestedScrollingEnabled(false);
productsRecyclerView.setHasFixedSize(true);
productsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
ProductsContentAdapter productsContentAdapter = new ProductsContentAdapter(products);
productsRecyclerView.setAdapter(productsContentAdapter);
return root;
}
我看过有关此问题的帖子:
如何将RecyclerView放在NestedScrollView中?
I have seen this post about the issue:
How to put RecyclerView inside NestedScrollView?
但是不幸的是,它没有提到对该问题的最终解决方案.
But it doesn't mention a final fix to the issue sadly.
要澄清: RecyclerView可以完美滚动,可以在正确的时间显示,但是问题是它可以立即渲染其所有子级,即使屏幕一次最多只能显示5-6个元素,也可能包含数百个元素.
To clarify: The RecyclerView scrolls perfectly, it shows at the correct time, but the issue is that it renders ALL of its children instantly, meaning possible several hundreds of elements, even though the screen only shows 5-6 at a time at max.
如果需要更多信息,请随时提问.
Please feel free to ask questions if more information is needed.
-------编辑-------
经过其他解决方案的多次失败尝试后,我最终使用了Jeeva Nandhan的解决方案.
在问这个问题之前,我知道这是一个可能的解决方案,但是我有11种可能需要适合RecyclerView的视图,所以我希望避免使用它.
使用不同的ViewType后,它可以完美运行.我担心由于ViewType的数量过多,效率会很低,但它像黄油一样光滑.
------- EDIT -------
After many failed attempts of other solutions, i ended up using Jeeva Nandhan's solution.
Prior to asking this question i knew that was a possible solution, but i had 11 different possible views that needed to fit into the RecyclerView, so i would've liked to avoid it.
After using different ViewTypes, it worked perfectly. I was afraid it would be very inefficient due to the high amount of ViewTypes, but it's buttery smooth.
推荐答案
我也遇到过这个问题...这是因为scrollview
和RecyclerView
在加载数据上都不同,因为ScrollView
起作用在这种情况下,作为父级,我们在代码中使用以下行.
I too have come across this issue... This is because both scrollview
and RecyclerView
are different in loading data, since the ScrollView
acts as the parent in this case and we are using the below line in our code.
setNestedScrollingEnabled(false);
这将根据Recyclerview
数据使滚动变慢并挂起.
This will make the scroll slow and hang issue based on the Recyclerview
data.
我用来解决此问题的一种方法是将标头添加到Recyclerview
.
One way which I have used to solve this issue is adding header to the Recyclerview
..
在这里,我会清楚地说明.
Here I'll explain it clearly.
让我们假设此recyclerview
在我们的活动中.
lets assume this recyclerview
is in our activity.
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
适配器类将是这样,我们将在其中添加标题
The adapter class will be like this, where we will add the header
public class SampleAdapter extends RecyclerView.Adapter {
private final int BODY = 1;
private final int HEADER = 2;
private List<String> data = null;
SampleAdapter(List<String> data) {
this.data = data;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return HEADER;
}
return BODY;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case HEADER:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_header_layout, parent, false);
return new HeaderViewHolder(view);
default:
//Setting the Body view...
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_details, parent, false);
return new BodyViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof BodyViewHolder) {
//Set the body content....
if (data != null && data.size() > 0) {
/** Since we have added one cell for header,
* we need to decrement the position and render the body view.
*
*/
int bodyPosition = position - 1;
}
} else if (holder instanceof HeaderViewHolder) {
//Set the header content...
}
}
@Override
public int getItemCount() {
//Sice we are going to add header, we are supposed increase the count by one...
return data.size() + 1;
}
}
因此,无需NestedScrollView
,所有视图都将以RecyclerView
行为工作...
by this there is no need for NestedScrollView
and all the view will work in RecyclerView
behavior...
希望这会有所帮助:)
这篇关于NestedScrollView中的RecyclerView导致RecyclerView膨胀所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!