Fußzeilenansicht in ListView ausblenden?

78

Ich habe eine ListView. Die Daten dahinter werden aus dem Internet in Sätzen von 10 bis 30 Elementen abgerufen, wenn der Benutzer ganz nach unten scrollt. Um anzuzeigen, dass mehr Elemente geladen werden, habe ich addFooterView()eine einfache Ansicht hinzugefügt, in der die Meldung "Laden ..." und ein Drehfeld angezeigt werden. Wenn ich keine Daten mehr habe (keine Daten mehr abzurufen), möchte ich diese Nachricht ausblenden. Ich habe versucht zu tun:

loadingView.setVisibility(View.GONE);

Obwohl dies die Ansicht verbirgt, lässt es leider Platz dafür. Das heißt, ich habe eine große Leerstelle, in der sich früher die Nachricht "Laden" befand. Wie kann ich diese Ansicht richtig ausblenden?

Ich kann nicht verwenden, removeFooterView()da ich es möglicherweise addFooterView()erneut anzeigen muss. In diesem Fall kann ich nicht erneut anrufen , da bereits ein Adapter auf dem eingestellt ListViewwurde und Sie addHeaderView()/ addFooterView()nach dem Festlegen eines Adapters nicht aufrufen können .

Felix
quelle

Antworten:

84

Es scheint, dass Sie addHeaderView()/ addFooterView() after aufrufen dürfen, setAdapter()solange Sie eine dieser Methoden mindestens einmal zuvor aufrufen . Das ist eine ziemlich schlechte Designentscheidung von Google, daher habe ich ein Problem eingereicht . Kombinieren Sie dies mit removeFooterView()und Sie haben meine Lösung.

+1 für die beiden anderen Antworten, die ich erhalten habe, sind gültige (und wohl korrektere) Lösungen. Meins ist jedoch das einfachste, und ich mag Einfachheit, daher werde ich meine eigene Antwort als akzeptiert markieren.

Felix
quelle
6
Dies scheint für Header nicht zu funktionieren. Ich kann nach setAdapter eine Fußzeile hinzufügen, aber keine Kopfzeile.
CottonBallPaws
1
+1 zum Speichern von RIESIGEN Kopfschmerzen. Ich frage mich, wie lange ich gebraucht hätte, um herauszufinden, dass Sie die Fußzeile hinzufügen mussten, bevor Sie den Adapter einstellen. (dumm)
Ross Hambrick
Ich habe festgestellt, dass die Bildlaufposition zurückgesetzt wird, wenn Sie die untere Position entfernen. Wenn Sie also das Überschreiben -> die Fußzeile entfernen, bevor Sie das Überschreiben beenden, springt sie zum Ende der Liste zurück. Bist du darauf gestoßen?
Vadim Peretokin
Trotzdem bin ich auf dasselbe Problem gestoßen wie littleFluffyKitty. Ich werde mit einem benutzerdefinierten Adapter gehen müssen.
Vadim Peretokin
Tolle Antwort, einfach! +100 für die Einreichung der Probleme bei Google.
Tomasz
37

Versuchen Sie, die Höhe der Fußzeile auf 0px oder 1px einzustellen, bevor Sie sie ausblenden. Alternativ können Sie die Fußzeilenansicht in eine wrap_contentHöhe einwickeln und die Innenansicht FrameLayoutausblenden / anzeigen, wobei die FrameLayoutsichtbare Ansicht erhalten bleibt. Die Höhe sollte sich dann richtig wickeln.

Yoni Samlan
quelle
Wie erzwingen Sie das Einstellen der Höhe der Ansicht? Ich habe versucht, setMinimumHeight (0); vor dem Verstecken scheint aber nicht zu funktionieren. Ich habe es auf GONE gesetzt, aber der Raum der Zelle bleibt immer noch zurück.
Maurice
Die Höhe und Breite sind Layoutparameter, daher müssen Sie das LayoutParameters-Objekt für die Ansicht mit der neuen Breite / Höhe festlegen. Siehe diese SO-Antwort: stackoverflow.com/a/2767142/59058 . Grundsätzlich sind Breite, Höhe und Ränder Eigenschaften, die wirklich für den Container der Ansicht gelten, nicht für die Ansicht selbst. Daher verwenden Sie ein übergeordnetes LayoutParameter-Objekt, um sie zu definieren.
Yoni Samlan
Ich glaube nicht, dass das für einen Header funktioniert. Ich habe null für einen Header erhalten, der angehängt wurde und getLayoutParams () für heißt.
Vadim Peretokin
5

In meinem Fall verursachen addFooterView / removeFooterView () einige Artefakte. Und ich habe eine andere Lösung gefunden. Ich habe FrameLayout als FooterView verwendet. Und wenn ich Footer hinzufügen möchte, habe ich mFrameFooter.addView (myFooter) aufgerufen. und mFrameFooter.removeAllViews (); zum entfernen.

FrameLayout frameLayout = new FrameLayout(this);
listView.addFooterView(frameLayout);
......
......
//For adding footerView
frameLayout.removeAllViews();
frameLayout.addView(mFooterView);
//For hide FooterView
frameLayout.removeAllViews();
Präzeptron
quelle
Arbeiten wie ein Zauber. Es sollte die akzeptierte Antwort sein :)
König der Massen
4

Funktioniert gut in meinem Projekt:

1.Fügen Sie zuerst die Fußzeilenansicht hinzu

mListView.addFooterView(mFooterView); mListView.setAdapter(mAdapter);

2.Stellen Sie die Sichtbarkeit ein

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, 0, 0, 0);

3. Unsichtbarkeit einstellen

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, -1*mFooterView.getHeight(), 0, 0);

Geek4IT
quelle
2

Wie @YoniSamlan betonte, kann dies auf einfache Weise erreicht werden. Sie müssen angeben

android:layout_height="wrap_content" 

in der ViewGroup, die die Schaltfläche "Mehr laden" enthält. Muss nicht FrameLayout sein, siehe unten für ein einfaches Arbeitsbeispiel, das ein LinearLayout verwendet.

Beide Bilder zeigen einen Bildschirm, der ganz nach unten gescrollt ist. Zuerst hat man eine sichtbare Fußzeile, die sich um die Schaltfläche "Mehr laden" dreht. Das zweite Bild zeigt, dass die Fußzeile zusammenfällt, wenn Sie die Sichtbarkeit der Schaltfläche auf GONE setzen.

Sie können die Fußzeile (innerhalb eines Rückrufs) erneut anzeigen, indem Sie die Sichtbarkeit ändern:

loadMore.setVisibility(View.VISIBLE);  // set to View.GONE to hide it again

listView mit sichtbarer Fußzeile listView mit Fußzeile weg

Führen Sie die listView-Initialisierung wie gewohnt durch

    // Find View, set empty View if needed
    mListView = (ListView) root.findViewById(R.id.reservations_search_results);
    mListView.setEmptyView(root.findViewById(R.id.search_reservations_list_empty));

    // Instantiate footerView using a LayoutInflater and add to listView
    footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
            .inflate(R.layout.load_more_footer_view, null, false);
    // additionally, find the "load more button" inside the footer view
    loadMore = footerView.findViewById(R.id.load_more);
    loadMore.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fetchData();
        }
    });

    // add footer view to the list
    mListView.addFooterView(footerView);

    // after we're done setting the footerView, we can setAdapter
    adapter = new ReservationsArrayAdapter(getActivity(), R.layout.list_item_reservations_search, reservationsList);
    mListView.setAdapter(adapter);

load_more_footer_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<Button
    android:id="@+id/load_more"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="9dp"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@drawable/transparent_white_border"
    android:textColor="@android:color/white"
    android:text="@string/LOAD_MORE"/>

kouretinho
quelle
2

Es sollte ein Fehler von Android sein.

Sie müssen die Fußzeilenansicht nicht dynamisch entfernen oder hinzufügen. Sie müssen nur ein nicht angegebenes übergeordnetes Höhenlayout erstellen (entweder aus einer XML-Datei aufblasen oder programmgesteuert erstellen) und dann Ihre Ansicht hinzufügen, die Sie ausblenden oder anzeigen möchten.

Und Sie können die Ansicht, aber NICHT das übergeordnete Layout, jetzt auf SICHTBAR oder GEGANGEN oder etwas anderes setzen. Für mich geht das.

Licht
quelle
0

Benutzt

footer.removeAllViews();

Dadurch wird die Fußzeile nicht entfernt, sondern Kinder werden gespült. Sie müssen wieder Kinder neu bevölkern. Kann vorbeischauen

footer.getChildCount()<2
Rahul
quelle
0

Ich fand auch, dass ein möglicher Aufruf onContentChanged()(wenn Sie verwenden ListActivity) ist, um die Neuerstellung zu erzwingen, ListViewwenn ich HeaderViewsie nach dem setAdapter()Aufruf hinzufügen muss , aber es ist ein sehr hässlicher Hack.

Atom
quelle
0

Ich habe eine ListView erstellt, die dies behandelt. Es besteht auch die Möglichkeit, den von mir erstellten EndlessScrollListener für endlose Listenansichten zu verwenden, mit denen Daten geladen werden, bis keine Daten mehr geladen werden müssen.

Sie können diese Klassen hier sehen:

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Hilfsprogramm zur Verwendung des Funktionen ohne Erweiterung von SimpleListViewWithLoadingIndicator.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Listener, der Daten lädt, wenn der Benutzer ist im Begriff, den unteren Rand der ListView zu erreichen.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Sie können diese Klasse direkt verwenden oder erweitern.

Fernando Camargo
quelle
0

Ich habe einen kleinen Hack-Weg, um dieses Problem für überall zu lösen. Fügen Sie die Listenansicht und die Fußzeilenansicht (nur das Unterlayout) wie LinnearLayout in das übergeordnete Layout ein. Denken Sie daran, dass die Fußzeilenansicht unter der Listenansicht liegt.

Steuern Sie diese Fußzeilenansicht weg und die Sichtbarkeit wie die Nominalansicht. Und fertig!

cuasodayleo
quelle
0

Zuerst füge ich meine Fußzeile der Listenansicht hinzu

listView.addFooterView(Utils.b);

Dann auf Knopfdruck, entferne ich die Ansicht,

listView.removeFooterView(Utils.b);

Ich füge die Fußzeile jedes Mal hinzu, wenn ich den Async drücke, und sie sind keine doppelten Einträge. Ich könnte auch nach der Zählung suchen und so ist es,

if(listView.getFooterViewsCount() > 0){//if footer is added already do something}
Syeda
quelle
-1

Wenn Sie die Fußzeile entfernen möchten, ListViewrufen Sie einfach an

listView.addFooterView(new View(yourContext)); 

Es wird eine leere Dummy-Ansicht hinzugefügt, die keinen Platz reserviert

Kareem
quelle
1
In der Dokumentation heißt es: "Wenn addFooterView mehrmals aufgerufen wird, werden die Ansichten in der Reihenfolge angezeigt, in der sie hinzugefügt wurden."
Max4ever