在 NestedScrollView 中使用两个具有不同适配器的 RecyclerView 加载速度非常慢

Posted

技术标签:

【中文标题】在 NestedScrollView 中使用两个具有不同适配器的 RecyclerView 加载速度非常慢【英文标题】:Use two RecyclerView with different adapter inside NestedScrollView load very slowly 【发布时间】:2020-06-01 00:43:31 【问题描述】:

我需要在同一个视图中使用两个具有不同适配器的 RecyclerView。

我的第一个 RecyclerView 只会在 onCreate 中加载一次。

当用户滚动到底部并调用 api 获取新数据时,我的 Second RecyclerView 将加载越来越多的数据。

当我让我的 Second RecyclerView 调用 api 加载越来越多的数据时,它会加载非常缓慢并且滚动很重。

我该如何解决这个问题,谢谢!

这是我的片段:

public class NewFragment extends Fragment 

    private void setRecyclerAndAdapter()
        if(swipeRefreshLayout != null && postRecycler != null)

            layoutManager = new LinearLayoutManager(context); 
            postRecycler.setLayoutManager(layoutManager);

            LayoutAnimationController animationController = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_up_to_down);
            postRecycler.setLayoutAnimation(animationController);

            if(postAdAdapter == null)
                postAdAdapter = new PostCardAdapter(context, postDataList);
                postRecycler.setAdapter(postAdAdapter);

                setListener();
            else
                postAdAdapter.notifyDataSetChanged();
            
        else
            return;
    
.
    private void setListener()
        if(swipeRefreshLayout != null && postRecycler != null)

            ......

            nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() 
                @Override
                public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) 
                    if(v.getChildAt(v.getChildCount() - 1) != null) 
                        if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) &&
                                scrollY > oldScrollY) 

                            visibleItemCount = layoutManager.getChildCount();
                            totalItemCount = layoutManager.getItemCount();
                            pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();

                            if(controlCanGetMorePostData == true)
                                controlCanGetMorePostData = false;

                                if(postAdAdapter != null)
                                    if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) 
                                        postAdAdapter.setLoadState(postAdAdapter.LOADING);
                                        callApiManagerGetMoreData();
                                    
                                else
                                    return;
                            
                            else
                                hasMorePostData = false;
                                setMoreDataState();
                            
                        
                    
                
            );
        else
            return;
    


这是我的布局:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/fragment_new_swipe_refresh"
        android:layout_
        android:layout_>

        <androidx.core.widget.NestedScrollView
            android:id="@+id/fragment_new_nestedScroll"
            android:layout_
            android:layout_
            android:fillViewport="true"
            android:scrollbars="none">

                <GridLayout
                    android:layout_
                    android:layout_
                    android:columnCount="1"
                    android:rowCount="2">

                        <RelativeLayout
                            android:id="@+id/fragment_new_banner_content"
                            android:layout_
                            android:layout_
                            android:layout_row="0">

                                <androidx.recyclerview.widget.RecyclerView
                                    android:id="@+id/fragment_new_first_recycler"
                                    android:layout_
                                    android:layout_
                                    android:scrollbars="vertical" />

                                <com.gmpsykr.each.Game.BannerIndicator
                                    android:id="@+id/fragment_new_banner_indicator"
                                    android:layout_
                                    android:layout_
                                    android:layout_alignBottom="@+id/fragment_new_banner_recycler"
                                    app:selectColor="@color/colorAccent"
                                    app:unselectedColor="#ffffff"
                                    app:radius="3dp"
                                    app:space="10dp" />

                        </RelativeLayout>

                        <androidx.recyclerview.widget.RecyclerView
                            android:id="@+id/fragment_new_second_recycler"
                            android:layout_
                            android:layout_
                            android:layoutAnimation="@anim/layout_animation_up_to_down"
                            android:layout_row="1" />

                </GridLayout>

        </androidx.core.widget.NestedScrollView>


</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

【问题讨论】:

试过这个吗? ***.com/a/37337641/9248098 @GowthamKK 我试过了,同样的问题。 @GowthamKK 如果你禁用了nestedScrolling 然后RecyclerView 将停止滚动视图,这实际上违背了拥有它的目的 @AshwiniViolet 好的,感谢您告诉我。我还没有研究过nestedScrolling 移除内部RelativeLayout。只需将 RecyclerView 保留在 LinearLayout 中 【参考方案1】:
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment_new_swipe_refresh"
    android:layout_
    android:layout_>

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_
            android:layout_>

                        <LinearLayout
                            android:layout_
                            android:layout_
                            android:orientation="vertical">

                                <RelativeLayout
                                    android:layout_
                                    android:layout_
                                    android:background="@color/colorAppPrimaryRed" />

                                <androidx.recyclerview.widget.RecyclerView
                                    android:id="@+id/fragment_new_recycler"
                                    android:layout_
                                    android:layout_
                                    android:nestedScrollingEnabled="false"
                                    android:layoutAnimation="@anim/layout_animation_up_to_down" />

                        </LinearLayout>


        </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

【讨论】:

我希望当我滚动recyclerview时,recyclerview上面的项目会一起滚动。我试过你的方法,该项目总是在顶部。【参考方案2】:

我希望您阅读此article 和https://***.com/a/37337641/11560055 的相同问题。

我认为这将是您问题的答案。

【讨论】:

我添加了recyclerView.setNestedScrollingEnabled(false),但是不行。

以上是关于在 NestedScrollView 中使用两个具有不同适配器的 RecyclerView 加载速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章

ConstraintLayout 内的 NestedScrollView 不可滚动

NestedScrollView内部的RecyclerView ViewHolder创建

内容更改时,NestedScrollView 在顶部滚动

Android:ScrollView 与 NestedScrollView

当在nestedscrollview的recyclerview中将项目拖出可见空间时-nestedscrollView不滚动

NestedScrollView使用和理解