RecyclerView recycelt Ansichten nicht, wenn es innerhalb von NestedScrollView verwendet wird

Lesezeit: 5 Minuten

Benutzer-Avatar
MAI3AM

Ich benutze RecyclerView Innerhalb NestedScrollView. Auch ich setze setNestedScrollingEnabled zu falsch für recyclerview

niedrigere API zu unterstützen

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

Jetzt! Wenn der Benutzer die Ansicht gescrollt hat, scheint alles in Ordnung zu sein, aber !!! Aufrufe in Recyclerview werden nicht recycelt!!! und die Heap-Größe wächst schnell!!

Aktualisieren: RecyclerView Layout-Manager ist StaggeredLayoutManager

fragment_profile.xml:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/profileSwipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

                <!-- RecyclerView and NestedScrollView -->
                <include layout="@layout/fragment_profile_details" />

        </android.support.v4.widget.SwipeRefreshLayout>

</android.support.design.widget.CoordinatorLayout>

fragment_profile_details.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:orientation="vertical" >

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/nested_scrollbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:fillViewport="true"
            android:scrollbars="none" >

                <LinearLayout
                    android:id="@+id/nested_scrollbar_linear"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:descendantFocusability="blocksDescendants"
                    android:orientation="vertical" >

                        <android.support.v7.widget.CardView
                            android:id="@+id/profileCardview"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            app:cardBackgroundColor="@color/card_backgroind"
                            app:cardCornerRadius="0dp"
                            app:cardElevation="0dp" >

                            <!-- Profile related stuff like avatar and etc. --->

                        </android.support.v7.widget.CardView>

                        <android.support.v7.widget.RecyclerView
                            android:id="@+id/list_view"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="@dimen/four"
                            android:layout_marginEnd="@dimen/four"
                            android:layout_marginLeft="@dimen/four"
                            android:layout_marginRight="@dimen/four"
                            android:layout_marginStart="@dimen/four"
                            android:layout_marginTop="@dimen/four"
                            app:layout_behavior="@string/appbar_scrolling_view_behavior"
                            android:clipToPadding="false" />

                </LinearLayout>
        </android.support.v4.widget.NestedScrollView>
</LinearLayout>

ProfileFragment.java:

mAdapter        = new MainAdapter(getActivity(), glide, Data);

listView        = (RecyclerView) view.findViewById(R.id.list_view);

ViewCompat.setNestedScrollingEnabled(listView, false);  
listView.setAdapter(mAdapter);

mStaggeredLM    = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mStaggeredLM.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);

listView.setLayoutManager(mStaggeredLM);

mScroll.setOnScrollChangeListener(new OnScrollChangeListener() {

        @Override
        public void onScrollChange(NestedScrollView arg0, int arg1, int arg2, int arg3, int arg4) {

            View view   = (View) mScroll.getChildAt(mScroll.getChildCount() - 1);
            int diff    = (view.getBottom() - ( mScroll.getHeight() + mScroll.getScrollY()));

            if(diff == 0){

                int visibleItemCount            = mStaggeredLM.getChildCount();
                int totalItemCount              = mStaggeredLM.getItemCount();

                int[] lastVisibleItemPositions  = mStaggeredLM.findLastVisibleItemPositions(null);
                int lastVisibleItemPos  = getLastVisibleItem(lastVisibleItemPositions);

                Log.e("getChildCount", String.valueOf(visibleItemCount));
                Log.e("getItemCount", String.valueOf(totalItemCount));
                Log.e("lastVisibleItemPos", String.valueOf(lastVisibleItemPos));

                if ((visibleItemCount + 5) >= totalItemCount) {

                    mLoadMore.setVisibility(View.VISIBLE);
                    Log.e("LOG", "Last Item Reached!");
                }

                mMore = true;
                mFresh = false;
                mRefresh = false;
                getPosts();
            }

        }

    });

Ps : Ich habe mehr laden auf Bildlaufansicht eingestellt, weil recyclerview Mach es kontinuierlich und nicht aufzuhalten!

Jede Hilfe ist willkommen

  • Können Sie den Grund erklären, warum Sie hinzugefügt haben RecyclerView Innerhalb NestedScrollView?

    – romtsn

    5. Juni 2016 um 7:27 Uhr

  • @rom4ek stackoverflow.com/questions/37437161/…

    – MAI3AM

    5. Juni 2016 um 8:17 Uhr


  • @MAY3AM aktualisiere deinen Code und XML

    – appukrb

    7. Juni 2016 um 5:31 Uhr

  • NestedScrollView zeichnet alle untergeordneten Elemente, also wenn RecyclerView wurde innen verwendet NestedScrollView Alle Elemente des Adapters werden zum ersten Mal selbst geladen. Ein besserer Ansatz wird sein, zu verwenden RecyclerView nur und verwenden getItmeViewType zurückgeben cardView if(position==0) in adapter. wie von Rehan vorgeschlagen.

    – Pr38y

    9. Juni 2016 um 10:21 Uhr

  • Ich gehe normalerweise mit @Pr38y. Welches Leistungsproblem hast du?

    – Zinn Tran

    11. Juni 2016 um 9:34 Uhr

Benutzer-Avatar
Arpit Ratan

Dies liegt daran, dass wir eine Recycler-Ansicht haben, die ein Scroll-Verhalten innerhalb einer Scroll-Ansicht hat. (innerhalb einer Schriftrolle scrollen)

Ich denke, der beste Weg, dieses Problem zu lösen, ist zu Ihnen ProfilKartenansicht als Kopfzeile in Ihrer Recycler-Ansicht und entfernen Sie dann die verschachtelte Bildlaufansicht.

Wenn es eine Listenansicht wäre, dann wäre es so einfach wie listView.addHeaderView(profileCardView), aber für die Recycler-Ansicht gibt es kein addheadview-Äquivalent. Daher können Sie auf den folgenden Link verweisen, um Ihre Implementierung zu ändern.

Gibt es ein addHeaderView-Äquivalent für RecyclerView?

Benutzer-Avatar
Neo

Für eine RecyclerView oder ListView sollte die Höhe konstant sein, denn wenn sie keine konstante Größe hat, dann wie wird die maximale Anzahl sichtbarer Zeilen im Speicher verwaltet. Versuchen Sie es, indem Sie das RecyclerView-Attribut ändern android:layout_height="match_parent" oder eine feste Höhe (zB "300dp" – nach Bedarf), statt "wrap_content". Es sollte Ihre Speicherverwaltung verbessern.

  • @CliveJefferies Das Festlegen von layout_height auf eine feste Größe reduziert das Neuzeichnen, wenn eine Unteransicht aktualisiert wird. Sie sagen sozusagen “Keine Sorge – Sie müssen diese Ansicht nicht neu zeichnen, wenn sich meine Unteransichten ändern, da sie eine feste Größe haben”. Theoretisch könnte man sagen, dass es den Speicherbedarf reduzieren könnte, aber vor allem wird es UI-blockierende Garbage Collections eliminieren, was Ihre App flüssiger macht.

    – Artur Vancans

    8. März 2019 um 13:52 Uhr


1226680cookie-checkRecyclerView recycelt Ansichten nicht, wenn es innerhalb von NestedScrollView verwendet wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy