Ich habe nach Lösungen für dieses Problem gesucht und die einzige Antwort, die ich finden kann, scheint zu sein: " Fügen Sie keine ListView in eine ScrollView ein ". Ich habe jedoch noch keine wirkliche Erklärung dafür, warum . Der einzige Grund, den ich zu finden scheint, ist, dass Google nicht der Meinung ist, dass Sie das tun sollten. Nun, das tue ich, also habe ich es getan.
Die Frage ist also, wie Sie eine ListView in eine ScrollView einfügen können, ohne dass sie auf ihre minimale Höhe reduziert wird.
ListView
.ListView
kann mehrere Zeilenstile sowie nicht auswählbare Zeilen haben.Antworten:
Die Verwendung von a
ListView
, damit es nicht gescrollt wird, ist extrem teuer und widerspricht dem gesamten Zweck vonListView
. Sie sollten dies NICHT tun. Verwenden SieLinearLayout
stattdessen einfach ein .quelle
How can I put a ListView into a ScrollView without it collapsing?
... Sie können sagen, dass Sie es nicht tun sollten, aber auch eine Antwort geben, wie es geht, das ist eine gute Antwort. Sie wissen, dass eine ListView neben dem Scrollen noch einige andere coole Funktionen bietet, die LinearLayout nicht bietet.Hier ist meine Lösung. Ich bin ziemlich neu in der Android-Plattform, und ich bin sicher, dass dies ein bisschen hackisch ist, insbesondere in dem Teil, in dem es darum geht, .measure direkt aufzurufen und die
LayoutParams.height
Eigenschaft direkt festzulegen , aber es funktioniert.Alles, was Sie tun müssen, ist anzurufen,
Utility.setListViewHeightBasedOnChildren(yourListView)
und die Größe wird so angepasst, dass sie genau der Höhe der Elemente entspricht.quelle
LinearLayout
hat nicht alle Feinheiten von aListView
- es hat keine Trennwände, Kopf- / Fußzeilenansichten, eine Listenauswahl, die den Farben des UI-Themas des Telefons entspricht usw. Ehrlich gesagt gibt es keinen Grund, warum Sie nicht scrollen können den inneren Container bis zum Ende und lassen Sie dann keine Berührungsereignisse mehr abfangen, sodass der äußere Container einen Bildlauf durchführt. Jeder Desktop-Browser tut dies, wenn Sie Ihr Scrollrad verwenden. Android selbst kann verschachteltes Scrollen verarbeiten, wenn Sie über den Trackball navigieren. Warum also nicht per Touch?listItem.measure(0,0)
löst eine NPE aus, wenn listItem eine ViewGroup-Instanz ist. Ich habelistItem.measure
if (listItem instanceof ViewGroup) listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
ListView
Dose Gegenstände mit variabler Höhe enthalten kann. Der Aufruf von gibtgetMeasuredHeight()
nur die angestrebte Mindesthöhe im Gegensatz zur tatsächlichen Höhe zurück. Ich habe versucht,getHeight()
stattdessen zu verwenden, aber dies gibt 0 zurück. Hat jemand einen Einblick, wie man das angeht?Dies wird auf jeden Fall Arbeit ............
Sie müssen nur Ihre ersetzen
<ScrollView ></ScrollView>
in das Layout mit dieser XML - DateiCustom ScrollView
wie<com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
quelle
Wenn wir nicht
ListView
in ein setzenScrollView
, können wir esListView
als verwendenScrollView
. Dinge, dieListView
drin sein müssen, können in dieListView
. Andere Layouts oben und untenListView
können durch Hinzufügen von Layouts zu Kopf- und Fußzeile von eingefügt werdenListView
. DasListView
Ganze gibt Ihnen also eine Erfahrung des Scrollens.quelle
Es gibt viele Situationen, in denen es sehr sinnvoll ist, ListViews in einer ScrollView zu haben.
Hier ist Code, der auf DougWs Vorschlag basiert ... arbeitet in einem Fragment, benötigt weniger Speicher.
Rufen Sie setListViewHeightBasedOnChildren (Listenansicht) für jede eingebettete Listenansicht auf.
quelle
ListView ist bereits in der Lage, sich selbst so zu messen, dass es groß genug ist, um alle Elemente anzuzeigen. Dies ist jedoch nicht der Fall, wenn Sie einfach wrap_content (MeasureSpec.UNSPECIFIED) angeben. Dies geschieht, wenn mit MeasureSpec.AT_MOST eine Höhe angegeben wird. Mit diesem Wissen können Sie eine sehr einfache Unterklasse erstellen, um dieses Problem zu lösen, die weitaus besser funktioniert als alle oben genannten Lösungen. Sie sollten für diese Unterklasse weiterhin wrap_content verwenden.
Wenn Sie die heightMeasureSpec so bearbeiten, dass sie AT_MOST mit einer sehr großen Größe (Integer.MAX_VALUE >> 4) ist, misst die ListView alle untergeordneten Elemente bis zur angegebenen (sehr großen) Höhe und stellt ihre Höhe entsprechend ein.
Dies funktioniert aus mehreren Gründen besser als die anderen Lösungen:
Auf der anderen Seite könnte man argumentieren, dass dies auf undokumentiertem Verhalten im SDK beruht, das sich ändern könnte. Auf der anderen Seite könnten Sie argumentieren, dass wrap_content auf diese Weise wirklich mit ListView funktionieren sollte und dass das aktuelle Verhalten von wrap_content nur fehlerhaft ist.
Wenn Sie befürchten, dass sich das Verhalten in Zukunft ändern könnte, sollten Sie einfach die Funktion onMeasure und die zugehörigen Funktionen aus ListView.java in Ihre eigene Unterklasse kopieren und dann den Pfad AT_MOST durch onMeasure auch für UNSPECIFIED ausführen.
Übrigens glaube ich, dass dies ein absolut gültiger Ansatz ist, wenn Sie mit einer kleinen Anzahl von Listenelementen arbeiten. Es mag im Vergleich zu LinearLayout ineffizient sein, aber wenn die Anzahl der Elemente gering ist, ist die Verwendung von LinearLayout eine unnötige Optimierung und daher unnötige Komplexität.
quelle
Es gibt eine eingebaute Einstellung dafür. In der ScrollView:
In Java
Romain Guy erklärt es hier ausführlich: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
quelle
Sie erstellen eine benutzerdefinierte Listenansicht, die nicht scrollbar ist
In Ihrer Layout-Ressourcendatei
In der Java-Datei
Erstellen Sie ein Objekt Ihrer customListview anstelle von ListView wie folgt: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);
quelle
Wir konnten nicht zwei gleichzeitig scrollen. Wir haben die Gesamtlänge von ListView und erweitern die Listenansicht um die Gesamthöhe. Dann können wir ListView direkt in ScrollView oder mit LinearLayout hinzufügen, da ScrollView direkt ein Kind hat. Kopieren Sie die Methode setListViewHeightBasedOnChildren (lv) in Ihren Code und erweitern Sie die Listenansicht. Anschließend können Sie die Listenansicht in der Bildlaufansicht verwenden. \ layout xml Datei
onCreate-Methode in der Aktivitätsklasse:
quelle
Dies ist eine Kombination der Antworten von DougW, Good Guy Greg und Paul. Ich fand, dass alles benötigt wurde, wenn versucht wurde, dies mit einem benutzerdefinierten Listenansichtsadapter und nicht standardmäßigen Listenelementen zu verwenden, da sonst die Listenansicht die Anwendung zum Absturz brachte (auch mit der Antwort von Nex abstürzte):
quelle
Sie sollten eine ListView nicht in eine ScrollView einfügen, da dies bereits eine ListView ist ein Scroll. Das wäre also so, als würde man eine ScrollView in eine ScrollView einfügen.
Was versuchst du zu erreichen?
quelle
Ich habe @ DougW's
Utility
in C # konvertiert (in Xamarin verwendet). Das Folgende funktioniert gut für Elemente mit fester Höhe in der Liste und ist meistens in Ordnung oder zumindest ein guter Anfang, wenn nur einige der Elemente etwas größer als das Standardelement sind.Danke @DougW, das hat mich aus einer schwierigen Situation gebracht, als ich mit OtherPeople'sCode arbeiten musste. :-)
quelle
setListViewHeightBasedOnChildren()
Methode aufgerufen ? Weil es bei mir nicht immer funktioniert.Dies ist das einzige, was für mich funktioniert hat:
ab Lollipop können Sie verwenden
Wenn Sie das verschachtelte Scrollen für diese Ansicht aktivieren oder deaktivieren, müssen Sie die RecyclerView verwenden, wenn Sie eine Abwärtskompatibilität mit einer älteren Version des Betriebssystems benötigen.
quelle
Vorher war es nicht möglich. Mit der Veröffentlichung neuer Appcompat-Bibliotheken und Design-Bibliotheken kann dies jedoch erreicht werden.
Sie müssen nur NestedScrollView verwenden https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html verwenden
Ich weiß nicht, ob es mit Listview funktioniert oder nicht, aber mit RecyclerView.
Code-Auszug:
quelle
Hey, ich hatte ein ähnliches Problem. Ich wollte eine Listenansicht anzeigen, die nicht gescrollt wurde, und stellte fest, dass das Bearbeiten der Parameter funktioniert, aber ineffizient ist und sich auf verschiedenen Geräten unterschiedlich verhält. Daher ist dies ein Teil meines Zeitplancodes, der dies tatsächlich sehr effizient ausführt .
Hinweis: Wenn Sie dies verwenden,
notifyDataSetChanged();
funktioniert es nicht wie beabsichtigt, da die Ansichten nicht neu gezeichnet werden. Tun Sie dies, wenn Sie eine Lösung benötigenquelle
Bei der Verwendung einer ListView in einer ScrollView treten zwei Probleme auf.
1- ListView muss vollständig auf die untergeordnete Größe erweitert werden. Diese ListView löst dieses Problem:
Die Teilerhöhe muss 0 sein. Verwenden Sie stattdessen eine Auffüllung in Zeilen.
2- Die ListView verwendet Berührungsereignisse, sodass ScrollView nicht wie gewohnt gescrollt werden kann. Diese ScrollView behebt dieses Problem:
Dies ist der beste Weg, den ich gefunden habe, um den Trick zu machen!
quelle
Eine Lösung, die ich verwende, besteht darin, den gesamten Inhalt der ScrollView (was über und unter der listView sein sollte) als headerView und footerView in der ListView hinzuzufügen.
So funktioniert es wie, auch die Konvertierungsansicht wird so geändert, wie sie sein sollte.
quelle
Dank Vinays Code ist hier mein Code, wenn Sie keine Listenansicht in einer Bildlaufansicht haben können, aber so etwas brauchen
Das relativeLayout bleibt in einer ScrollView, sodass alles scrollbar wird :)
quelle
Hier ist kleine Änderung auf @djunod ‚s Antwort , die ich brauche , um es perfekt funktioniert:
quelle
versuche das, das funktioniert bei mir, ich habe vergessen, wo ich es gefunden habe, irgendwo im Stapelüberlauf, ich bin nicht hier, um zu erklären, warum es nicht funktioniert, aber das ist die Antwort :).
EDIT !, Ich habe endlich herausgefunden, woher ich den Code habe. Hier ! : ListView in ScrollView scrollt unter Android nicht
quelle
Obwohl die vorgeschlagenen setListViewHeightBasedOnChildren () -Methoden in den meisten Fällen funktionieren, habe ich in einigen Fällen, insbesondere bei vielen Elementen, festgestellt, dass die letzten Elemente nicht angezeigt werden. Daher habe ich beschlossen, eine einfache Version des ListView- Verhaltens nachzuahmen, um Adaptercode wiederzuverwenden. Hier ist die ListView-Alternative:
quelle
Alle diese Antworten sind falsch !!! Wenn Sie versuchen, eine Listenansicht in eine Bildlaufansicht einzufügen, sollten Sie Ihr Design überdenken. Sie versuchen, eine ScrollView in eine ScrollView einzufügen. Ein Eingriff in die Liste beeinträchtigt die Leistung der Liste. Es wurde von Android so entworfen.
Wenn Sie wirklich möchten, dass sich die Liste im selben Bildlauf wie die anderen Elemente befindet, müssen Sie nur die anderen Elemente mit einer einfachen switch-Anweisung in Ihrem Adapter oben in die Liste einfügen:
Der Listenadapter kann alles verarbeiten, da er nur das Renderbare wiedergibt.
quelle
Dieses ganze Problem würde einfach verschwinden, wenn LinearLayout eine setAdapter-Methode hätte, denn wenn Sie dann jemandem sagten, er solle sie verwenden, wäre die Alternative trivial.
Wenn Sie tatsächlich eine scrollende ListView in einer anderen scrollenden Ansicht wünschen, hilft dies nicht, aber ansonsten gibt Ihnen dies zumindest eine Idee.
Sie müssen einen benutzerdefinierten Adapter erstellen, um den gesamten Inhalt zu kombinieren, über den Sie scrollen möchten, und den ListView-Adapter darauf einstellen.
Ich habe keinen Beispielcode zur Hand, aber wenn Sie so etwas wollen.
Dann müssen Sie einen Adapter erstellen, der den gesamten Inhalt darstellt. Die ListView / Adapter sind intelligent genug, um auch verschiedene Typen zu verarbeiten, aber Sie müssen den Adapter selbst schreiben.
Die Android UI API ist einfach nicht so ausgereift wie so ziemlich alles andere da draußen, daher hat sie nicht die gleichen Feinheiten wie andere Plattformen. Wenn Sie etwas auf Android tun, müssen Sie sich in einer Android (Unix) -Mentalität befinden, in der Sie erwarten, dass Sie, um etwas zu tun, wahrscheinlich die Funktionalität kleinerer Teile zusammenstellen und eine Menge Ihres eigenen Codes schreiben müssen, um es zu erreichen Arbeit.
quelle
Wenn wir
ListView
hineinlegenScrollView
, entstehen zwei Probleme. EinerScrollView
misst seine Kinder im UNSPECIFIED-Modus,ListView
stellt also seine eigene Höhe ein, um nur einen Gegenstand aufzunehmen (ich weiß nicht warum), ein andererScrollView
fängt das Berührungsereignis so abListView
scrollt nicht.Aber wir können Platz
ListView
innenScrollView
mit etwas Abhilfe. Dieser Beitrag von mir erklärt die Problemumgehung. Durch diese Problemumgehung können wir auch dieListView
Recyclingfunktion beibehalten .quelle
Anstatt die Listenansicht in die Bildlaufansicht einzufügen, platzieren Sie den Rest des Inhalts zwischen der Listenansicht und dem Öffnen der Bildlaufansicht als separate Ansicht und legen Sie diese Ansicht als Kopfzeile der Listenansicht fest. So erhalten Sie schließlich nur die Listenansicht, die Scroll übernimmt.
quelle
Diese Bibliothek ist die einfachste und schnellste Lösung für das Problem.
quelle
Hier ist meine Version des Codes, der die Gesamthöhe der Listenansicht berechnet. Dieser funktioniert für mich:
quelle