Hoe gebruik ik RecyclerView in NestedScrollView?

Hoe gebruik je minHeightin NestedScrollView?
minHeightinhoud is niet zichtbaar na het instellen van de adapter.

UPDATElay-outcode bijgewerkt.

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/keyline_1">
    </RelativeLayout>
    <View
        android:id="@+id/separator"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#e5e5e5" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/conversation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

Antwoord 1, autoriteit 100%

Vervang uw recyclerView door,

<android.support.v7.widget.RecyclerView
    android:id="@+id/conversation"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

hier,

app:layout_behavior="@string/appbar_scrolling_view_behavior"

zal de rest regelen.

Nog één ding: u hoeft uw recyclerView niet in NestedScrollView te plaatsen


Antwoord 2, autoriteit 53%

UPDATE 1

Sinds Android Support Library 23.2.0 is er methode setAutoMeasureEnabled(true)toegevoegd voor LayoutManagers. Het zorgt ervoor dat RecyclerView zijn inhoud inpakt en werkt als een charme.
http://android-developers.blogspot.ru/2016 /02/android-support-library-232.html

Dus voeg iets als dit toe:

   LayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setAutoMeasureEnabled(true);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setNestedScrollingEnabled(false);

UPDATE 2

Sinds 27.1.0 setAutoMeasureEnabledis verouderd, moet u een aangepaste implementatie van LayoutManager bieden met een overschreven methode isAutoMeasureEnabled()

Maar na veel gebruik van RecyclerView raad ik ten zeerste aan om het niet in inpakmoduste gebruiken, omdat dit niet is waarvoor het bedoeld is. Probeer je hele lay-out te refactoren met de normale enkele RecyclerView met verschillende typen items. Of gebruik de benadering met LinearLayout die ik hieronder heb beschreven als laatste redmiddel

Oud antwoord (niet aanbevolen)

Je kunt minHeightgebruiken in NestedScrollView.
Allereerst moet u uw eigen aangepaste LinearLayoutManagerimplementeren, het zorgt ervoor dat uw minHeightde inhoud ervan inpakt.
Bijvoorbeeld:

public class WrappingLinearLayoutManager extends LinearLayoutManager
{
    public WrappingLinearLayoutManager(Context context) {
        super(context);
    }
    private int[] mMeasuredDimension = new int[2];
    @Override
    public boolean canScrollVertically() {
        return false;
    }
    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
            int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);
        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            if (getOrientation() == HORIZONTAL) {
                measureScrapChild(recycler, i,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        heightSpec,
                        mMeasuredDimension);
                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                measureScrapChild(recycler, i,
                        widthSpec,
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                        mMeasuredDimension);
                height = height + mMeasuredDimension[1];
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }
        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }
        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }
        setMeasuredDimension(width, height);
    }
    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
            int heightSpec, int[] measuredDimension) {
        View view = recycler.getViewForPosition(position);
        if (view.getVisibility() == View.GONE) {
            measuredDimension[0] = 0;
            measuredDimension[1] = 0;
            return;
        }
        // For adding Item Decor Insets to view
        super.measureChildWithMargins(view, 0, 0);
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(
                widthSpec,
                getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
                p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(
                heightSpec,
                getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
                p.height);
        view.measure(childWidthSpec, childHeightSpec);
        // Get decorated measurements
        measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
        measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}

Gebruik daarna deze LayoutManagervoor uw minHeight

recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));

Maar u moet ook deze twee methoden aanroepen:

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

Hier setNestedScrollingEnabled(false)schakel scrollen uit voor minHeight, zodat het de scrollgebeurtenis van NestedScrollViewniet onderschept. En setHasFixedSize(false)bepaalt dat wijzigingen in de inhoud van de adapter de grootte van de minHeight

kunnen veranderen

Belangrijke opmerking:deze oplossing is in sommige gevallen een beetje buggy en heeft problemen met de prestaties, dus als je veel items in je minHeighthebt, raad ik je aan om gebruik aangepaste LinearLayout-gebaseerde implementatie van lijstweergave, maak er een analoog van Adapter voor en laat het zich gedragen als ListViewof minHeight


Antwoord 3, autoriteit 53%

  1. U moet ondersteuningsbibliotheek 23.2.0 (of) hierboven gebruiken

  2. De hoogte van

  3. en minHeightis wrap_content.

  4. recyclerView.setNestedScrollingEnabled(false)

Maar door dit te doen, werkt het recyclerpatroon niet. (dwz alle weergaven worden in één keer geladenomdat wrap_contentde hoogte van volledige minHeightnodig heeft, zodat alle onderliggende Viewstegelijk. Er wordt geen weergave hergebruikt). Probeer dit patroon niet te gebruiken, tenzij het echt nodig is. Probeer viewTypete gebruiken en voeg alle andere weergaven toe die moeten worden gescrolld naar minHeightin plaats van minHeightte gebruiken in Scrollview. De impact op de prestaties zal erg groot zijn.

Om het eenvoudig te maken “het werkt gewoon als LinearLayoutmet alle onderliggende weergaven”


Antwoord 4, autoriteit 15%

Je kunt android:fillViewport="true"gebruiken om NestedScrollViewde minHeightte laten meten. De minHeightvult de resterende hoogte. dus als je door de NestScrollViewwilt scrollen, kun je de minHeightvan de minHeightinstellen.


Antwoord 5, autoriteit 11%

Gewoon recyclerView.setNestedScrollingEnabled(false);toevoegen voordat setAdapterzelf voor mij werkte. Ik heb app:layout_behavior="@string/appbar_scrolling_view_behavior"nergens toegevoegd & geen aangepaste lay-outmanager ingesteld

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                android:text="Some Text..."
                android:padding="15dp" />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:padding="15dp"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Quick Links"
                android:textColor="@color/black"
                android:textStyle="bold"
                android:textAllCaps="true"
                android:paddingLeft="20dp"
                android:drawableLeft="@drawable/ic_trending_up_black_24dp"
                android:drawablePadding="10dp"
                android:layout_marginBottom="10dp"
                android:textSize="16sp"/>
            <View
                android:layout_width="fill_parent"
                android:layout_height="1dp"
                android:background="#efefef"/>
            <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

Antwoord 6, autoriteit 9%

Dit is wat voor mij werkt

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>

Antwoord 7, autoriteit 7%

Voor androidxheet het androidx.core.widget.NestedScrollView– en het scrollt gelijk boter met eigenschappen isScrollContaineren measureAllChildreningeschakeld:

<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:isScrollContainer="true"
    android:measureAllChildren="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fastScrollEnabled="true"
        android:scrollbarStyle="insideInset"
        android:scrollbars="vertical"
        android:splitMotionEvents="false"
        android:verticalScrollbarPosition="right"/>
</androidx.core.widget.NestedScrollView>

Antwoord 8, autoriteit 4%

Er is een eenvoudige en testende code die u kunt controleren

<android.support.v4.widget.NestedScrollView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v7.widget.RecyclerView
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>
   </android.support.v4.widget.NestedScrollView>

Antwoord 9, autoriteit 3%

Ik gebruikte RecyclerViewin een NestedScrollViewen het werkte voor mij. Het enige probleem dat ik in gedachten moest houden, was dat een NestedScrollView slechts één onderliggende weergave gebruikt. Dus in mijn geval gebruikte ik de LienearLayout-weergavegroep die mijn RecyclerView bevatte plus een aantal andere weergaven die ik nodig had.

Ik ervaar een probleem door mijn RecyclerView in de NestedScrollView te plaatsen. Ik realiseerde me dat het scrollen door de inhoud van mijn RecyclerView verslapte.

Later realiseerde ik me dat mijn RecyclerView de scroll-gebeurtenis ontving en daarom in strijd was met het scroll-gedrag van de NestedScrollView.

Dus om dat probleem op te lossen, moest ik de scroll-functionaliteit van mijn RecyclerView uitschakelen met deze methode movieListNewRecyclerView.setNestedScrollingEnabled(false);

Je kunt op mijn Instagram kijken voor een korte video van wat ik werkelijk heb gedaan. Dit is mijn instagram-handvat ofelix03

Klik op deze afbeelding om te zien wat ik deed


Antwoord 10, autoriteit 3%

Probeer deze bibliotheek te gebruiken – https://github.com/serso/android- linear-layout-manager.

LayoutManager van de bibliotheek zorgt ervoor dat RecyclerView de inhoud omhult. In dit geval zal RecyclerView “zo groot zijn als innerlijke weergaven”, dus het heeft geen schuifbalken en de gebruiker zal de schuifmogelijkheden van NestedScrollView gebruiken. Daarom zal het niet dubbelzinnig zijn zoals “scrollable inside scrollable”.


Antwoord 11, autoriteit 3%

Hier is de code die ik gebruik om scrollproblemen te voorkomen:

mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);

Antwoord 12, autoriteit 2%

Ik heb Viewpager en RecyclerView in de NestedScrollView. Na het toevoegen van onderstaande regels

recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);

Ik heb het probleem met langzaam scrollen en scrollvertraging opgelost.


Antwoord 13, autoriteit 2%

als je RecyclerViewin NestedScrollViewwilt gebruiken, is dit een simpele lastige, stel gewoon:

RecyclerView

  • recyclerView.setHasFixedSize(false) (java/kt)

  • android:nestedScrollingEnabled=”false”

  • android:layout_height=”wrap_content”

  • android:overScrollMode=”nooit”

NestedScrollView

  • android:fillViewport=”true”

dit is werk voor mij, en je kunt hier ook veel RecyclerView in NestedScrollView mee gebruiken.


Antwoord 14

Als u RecyclerView-23.2.1of hoger gebruikt. De volgende oplossing werkt prima:

Voeg RecyclerView als volgt toe aan uw lay-out:

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

En in je java-bestand:

RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));

Hier zal layoutManager.setAutoMeasureEnabled(true);het lukken.

Bekijk dit probleemen deze ontwikkelaarsblogvoor meer informatie.


Antwoord 15

Als je RecyclerView ScrollListenerin NestedScrollViewgebruikt, werkt de addOnScrollListener-listener niet goed als je beide gebruikt.

Gebruik deze code.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState); 
              ......
        }
    });

deze code werkt prima RecyclerView ScrollListenerbinnen NestedScrollView.

bedankt


Antwoord 16

Je kunt geen recycler-weergave gebruiken binnen een geneste scroll-weergave. Het is niet bedoeld om verdere schuifbare weergaven te bevatten, maar omdat het een kind is van een schuiflay-out zelf, hebt u de geneste schuifweergave nodig. Ik had hetzelfde probleem, maar uiteindelijk heb ik mijn tekstweergave verplaatst naar een headerview binnen de recyclerview, de recyclerview een direct kind van de coördinatorlay-out gemaakt en de geneste scrollweergave verwijderd. Toen waren al mijn problemen weg.


Antwoord 17

Een oplossing om de recyclingfunctie van de recyclerview te behouden en te voorkomen dat de recyclerview al uw gegevens laadt, is door een vaste hoogte in de recyclerview zelf in te stellen. Door dit te doen, is de recyclerview beperkt tot het laden van zoveel als de hoogte de gebruiker kan laten zien, waardoor het element wordt gerecycled als je ooit naar beneden/boven scrolt.


Antwoord 18

Er zijn veel goede antwoorden. De sleutel is dat je nestedScrollingEnabledmoet instellen op false. Zoals hierboven vermeld, kunt u het in java-code doen:

mRecyclerView.setNestedScrollingEnabled(false);

Maar je hebt ook de mogelijkheid om dezelfde eigenschap in xml-code in te stellen (android:nestedScrollingEnabled="false"):

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

19

Gebruik geen recycerview in NestedScrollView. Het kan wagenproblemen veroorzaken!
Ik stel voor het gebruik van ItemViewTypes in Recycerview voor het hanteren van meerdere soorten uitzichten.
Voeg gewoon een recycerview toe met Match_Parent-breedte en hoogte. DAN IN UW RECYCLERCERVIEWADAPTER HANDRIKTITMEVIEWEPTE EN GEBRUIK POSITIE VOOR HET HANDELING WELKE LAY-OUT TE WORDEN UITGEVOERD. Daarna kunt u uw kijkhouder aan het gebruik van OnbindView Houdingsmethode.

https://stacklearn.ir


20

Althans zo ver terug als Material Components 1.3.0-alpha03, het maakt niet uit of de RecyclerView is genest (in iets anders dan een ScrollView of NestedScrollView). Plaats gewoon app:layout_behavior="@string/appbar_scrolling_view_behavior"op zijn bovenliggende bovenliggende niveau dat een broer of zus is van de AppBarLayout in de CoordinatorLayout.

Dit werkte voor mij bij het gebruik van een enkele activiteitsarchitectuur met Jetpack Naviagation, waarbij alle fragmenten dezelfde AppBar delen vanuit de lay-out van de activiteit. Ik maak de FragmentContainer het directe kind van de CoordinatorLayout die ook de AppBarLayout bevat, zoals hieronder. De RecyclerViews in de verschillende fragmenten scrollen normaal en de AppBar klapt weg en verschijnt weer zoals verwacht.

   <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:defaultNavHost="true"
            app:navGraph="@navigation/mobile_navigation"/>
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:liftOnScroll="true">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                android:theme="?attr/actionBarTheme"
                app:layout_scrollFlags="scroll|enterAlways|snap" />
        </com.google.android.material.appbar.AppBarLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

liftOnScroll(gebruikt om app-balken eruit te laten zien alsof ze geen hoogte hebben wanneer ze bovenaan de pagina staan) werkt als elk fragment de ID van zijn RecyclerView doorgeeft aan AppBarLayout.liftOnScrollTargetViewIdin Fragment.onResume. Of geef 0 door als het fragment niet verschuift.


Antwoord 21

In mijn geval is het onderliggende item van NestedScrollview ConstraintLayout. Het werkt niet zoals verwacht, ik heb het vervangen door LinearLayout. Misschien helpt het iemand.

<androidx.core.widget.NestedScrollView 
  android:id="@+id/nestedScrollView" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent">
  <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:descendantFocusability="blocksDescendants">
    <androidx.recyclerview.widget.RecyclerView
      android:id="@+id/recyclerView"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:nestedScrollingEnabled="false" />
  </LinearLayout>
</androidx.core.widget.NestedScrollView>

Antwoord 22

RecyclerView met NestedScrollView

   <android.support.v7.widget.RecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Other episodes