Verwendung von RecyclerView
in NestedScrollView
? RecyclerView
Inhalt ist nach dem Einstellen des Adapters nicht sichtbar.
UPDATELayoutcode aktualisiert.
<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>
Ersetzen Sie Ihre RecyclerView durch
<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"
wird den Rest der Dinge schaffen.
Eine weitere Sache: Sie müssen Ihre RecyclerView nicht in NestedScrollView einfügen
UPDATE 1
Seit der Android Support Library 23.2.0 wurde die Methode setAutoMeasureEnabled(true)
für LayoutManager hinzugefügt. RecyclerView wird so verpackt, dass es den Inhalt einwickelt und wie ein Zauber wirkt.
http://Android-developers.blogspot.ru/2016/02/Android-support-library-232.html
Also einfach so etwas hinzufügen:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
UPDATE 2
Da 27.1.0 setAutoMeasureEnabled
veraltet ist, sollten Sie die benutzerdefinierte Implementierung von LayoutManager mit der überschriebenen Methode isAutoMeasureEnabled()
bereitstellen.
Nach vielen Anwendungsfällen von RecyclerView empfehle ich jedoch dringend, es nicht in Wrapping-Modus zu verwenden, da dies nicht beabsichtigt ist. Versuchen Sie, das gesamte Layout mit normalen Einzel-RecyclerView-Elementen mit verschiedenen Elementtypen zu überarbeiten. Oder verwenden Sie eine Methode mit LinearLayout, die ich als letztes Mittel beschrieben habe
Alte Antwort (nicht empfohlen)
Sie können RecyclerView
innerhalb von NestedScrollView
..__ verwenden. Zuerst sollten Sie Ihre eigene benutzerdefinierte LinearLayoutManager
implementieren. Dadurch wird Ihre RecyclerView
zum Umschließen des Inhalts verwendet. Zum Beispiel:
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);
}
}
Verwenden Sie danach diese LayoutManager
für Ihre RecyclerView
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
Sie sollten jedoch auch diese beiden Methoden aufrufen:
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Hier setNestedScrollingEnabled(false)
deaktivieren Sie das Scrollen für RecyclerView
, damit das Scrolling-Ereignis von NestedScrollView
nicht abgefangen wird. Und setHasFixedSize(false)
bestimmt, dass Änderungen am Adapterinhalt die Größe der RecyclerView
ändern können.
Wichtiger Hinweis: Diese Lösung ist in einigen Fällen ein wenig fehlerhaft und hat Probleme mit der Leistung. Wenn Sie also viele Elemente in Ihrer RecyclerView
haben, würde ich empfehlen, die benutzerdefinierte LinearLayout
- basierte Implementierung der Listenansicht zu verwenden Adapter dafür und verhalten Sie sich wie ListView
oder RecyclerView
1) Sie müssen die Unterstützungsbibliothek 23.2.0 (oder) oben verwenden
2) und RecyclerView
height sind wrap_content
.
3) recyclerView.setNestedScrollingEnabled(false)
Auf diese Weise funktioniert das Recycler-Muster jedoch nicht. (Das heißt, alle Ansichten werden auf einmal geladen, da wrap_content
die Höhe des vollständigen RecyclerView
benötigt, sodass alle untergeordneten View
s auf einmal gezeichnet werden. Keine Ansicht wird wiederverwendet). Verwenden Sie dieses Muster nur, wenn es wirklich erforderlich ist. Versuchen Sie, viewType
zu verwenden, und fügen Sie alle anderen Ansichten hinzu, die zu RecyclerView
scrollen müssen, anstatt RecyclerView
in Scrollview
zu verwenden. Die Auswirkungen auf die Leistung werden sehr hoch sein.
Um es einfach zu machen: "Es fungiert nur als LinearLayout
mit allen untergeordneten Ansichten."
Sie können Android:fillViewport="true"
verwenden, um NestedScrollView
das RecyclerView
messen zu lassen. RecyclerView
füllt die verbleibende Höhe. Wenn Sie also die NestScrollView
scrollen möchten, können Sie die RecyclerView
der minHeight
einstellen.
Einfach das Hinzufügen von recyclerView.setNestedScrollingEnabled(false);
vor setAdapter
für mich funktionierte. Ich habe an keiner Stelle app:layout_behavior="@string/appbar_scrolling_view_behavior"
hinzugefügt und keinen benutzerdefinierten Layout-Manager festgelegt
<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>
Das ist was für mich arbeiten
<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>
Versuchen Sie, diese Bibliothek zu verwenden - https://github.com/serso/Android-linear-layout-manager .
Der LayoutManager der Bibliothek lässt RecyclerView seinen Inhalt einschließen. In diesem Fall ist RecyclerView "so groß wie innere Ansichten", dass es keine Bildlaufleisten gibt und der Benutzer die Bildlauffunktionen von NestedScrollView verwendet. Daher ist es nicht mehrdeutig wie "scrollbar in scrollbar".
Es gibt einen einfachen und testenden Code, den Sie überprüfen können
<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>
Ich habe RecyclerView in einem NestedScrollView verwendet und es hat für mich funktioniert. Das einzige Problem, an das ich denken musste, war, dass ein NestedScrollView nur eine untergeordnete Ansicht hat. In meinem Fall verwendete ich die LienearLayout-Ansichtsgruppe, in der sich mein RecyclerView befand, sowie einige andere Ansichten, die ich brauchte.
Ich habe ein Problem, bei dem ich meine RecyclerView in die NestedScrollView stecke. Mir wurde klar, dass das Scrollen des Inhalts meines RecyclerView nachlässt.
Später erkannte ich, dass mein RecyclerView das Scrolling-Ereignis empfing und daher mit dem Scrollverhalten der NestedScrollView in Konflikt stand.
Um dieses Problem zu lösen, musste ich die Scroll-Funktionalität meines RecyclerView mit dieser Methode deaktivieren. movieListNewRecyclerView.setNestedScrollingEnabled(false);
Sie können mein Instagram für ein kurzes Video von mir überprüfen. Dies ist mein Instagram-Handle ofelix03
Hier der Code, den ich verwende, um Bildlaufprobleme zu vermeiden:
mRecyclerView = (RecyclerView) view.findViewById(Android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
Ich habe Viewpager und RecyclerView in der NestedScrollView. Nach dem Hinzufügen von Zeilen
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Ich habe das Problem des langsamen Bildlaufs und des Nachlaufs gelöst.
Wenn Sie RecyclerView-23.2.1
oder höher verwenden. Folgende Lösung wird gut funktionieren:
Fügen Sie in Ihrem Layout RecyclerView folgendermaßen hinzu:
<Android.support.v7.widget.RecyclerView
Android:id="@+id/review_list"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:scrollbars="vertical" />
Und in deiner Java-Datei:
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 wird layoutManager.setAutoMeasureEnabled(true);
den Trick tun.
Check out this issue und this developer blog für weitere Informationen.
Sie können eine Recycler-Ansicht nicht in einer verschachtelten Bildlaufansicht verwenden. Es ist nicht vorgesehen, weitere scrollbare Ansichten zu enthalten, da es sich jedoch um ein untergeordnetes Element eines Scroll-Layouts handelt, benötigen Sie die verschachtelte Scroll-Ansicht. Ich hatte das gleiche Problem, aber am Ende habe ich meine Textansicht verschoben, um eine Übersicht innerhalb der Recyclingübersicht zu sein, die Recyclingansicht zu einem direkten Kind des Koordinatorlayouts gemacht und die verschachtelte Scrollansicht gelöscht. Dann waren alle meine Probleme weg.
Es gibt viele gute Antworten. Der Schlüssel ist, dass Sie nestedScrollingEnabled
auf false
setzen müssen. Wie oben erwähnt, können Sie dies in Java-Code tun:
mRecyclerView.setNestedScrollingEnabled(false);
Sie haben aber auch die Möglichkeit, dieselbe Eigenschaft im XML-Code (Android:nestedScrollingEnabled="false"
) festzulegen:
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recyclerview"
Android:nestedScrollingEnabled="false"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
Für androidx
heißt es androidx.core.widget.NestedScrollView
- und scrollt auch wie Butter mit aktivierten Eigenschaften isScrollContainer
und measureAllChildren
:
<!-- 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>
Ich musste CoordinatorLayout mit dem Scrollen in der Symbolleiste implementieren, und es dauerte nur den ganzen Tag, um dieses Problem zu lösen. Ich habe es geschafft, NestedScrollView überhaupt zu entfernen. Also verwende ich RelativeLayout nur an der Wurzel.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/rv_nearby"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
verwenden Sie recyclerView nicht in NestedScrollView. Dies kann zu Kaskadenproblemen führen! Ich schlage vor, ItemViewTypes in RecyclerView zu verwenden, um mehrere Arten von Ansichten zu verarbeiten. Fügen Sie einfach eine RecyclerView mit übereinstimmender Breite und Höhe hinzu. Überschreiben Sie dann in Ihrem recyclerViewAdapter getItemViewType und verwenden Sie position, um zu bestimmen, welches Layout aufgeblasen werden soll. Danach können Sie Ihren Ansichtsinhaber mit der onBindViewHolder-Methode bearbeiten.
Wenn Sie RecyclerView ScrollListener innerhalb NestedScrollView verwenden, funktioniert der Listener addOnScrollListener nicht ordnungsgemäß, wenn Sie beide verwenden.
Verwenden Sie diesen Code.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
......
}
});
dieser Code funktioniert einwandfrei RecyclerView ScrollListener innerhalb NestedScrollView.
vielen Dank
Eine Lösung, um die Recyclingfunktion des Recyclingberichts beizubehalten und zu vermeiden, dass der Recyclingbericht alle Ihre Daten lädt, ist das Festlegen einer festen Höhe im Recyclingbericht. Auf diese Weise ist der Recycling-Bereich nur auf die Last begrenzt, deren Höhe dem Benutzer anzeigen kann, dass er sein Element wiederverwendet, wenn Sie nach oben/unten scrollen.