Hallo alle,
Ich entschuldige mich für die folgende lange Frage ...
Ich habe ein LinearLayout, das ein ListView und einige andere Elemente enthält. Wie bei der ListView ist jedes seiner Zeilen ein LinearLayout, das 3 Ansichten enthält - Checkbox, ImageView und TextView (von links nach rechts - horizontal). Da ich wollte, dass die ganze Reihe ausgewählt wurde, wenn der Trackball verwendet wurde (um mit einer Hintergrundfarbe hervorgehoben zu werden), stellte ich alle drei Ansichten in der Zeile LinearLayout als nicht fokussierbar ein und es funktionierte.
Jetzt habe ich 2 Probleme mit diesem ListView. Zuerst möchte ich, dass, wenn ich eine Zeile in der ListView (mit dem Finger) berühre, dasselbe Verhalten wie bei der Verwendung des Trackballs erreicht wird - bedeutet, dass die Zeile ausgewählt (hervorgehoben) werden soll. Was gerade passiert, ist, dass wenn ich die Zeile berühre, diese wirklich ausgewählt wird, aber wenn ich meinen Finger loslasse, ist die Auswahl weg (ähnlich wie es in der Kontaktliste des Geräts passiert).
Zweitens: In einem Menü kann ich ein neues LinearLayout anzeigen, anstatt eines, das ListView enthält (Bildschirm einer anderen Anwendung). Wenn das passiert, speichere ich noch das Objekt des LinearLayout, das die ListView enthält, weil ich es später wieder anzeigen möchte, ohne es neu zu erstellen. Das Problem ist, dass, wenn ich das LinearLayout mit der ListView wieder veröffentliche, keine Zeilen der ListView ausgewählt werden, auch wenn eine Zeile mit Zeilenabstand ausgewählt wurde, wenn das LinearLayout mit der ListView den Bildschirm "verließ".
Sorry nochmal für den langen Beitrag.
Danke!
Ja, aus der Sicht eines iOS-Entwicklers finde ich es extrem schwierig, Funktionen wie " Standardauswahl beim Start festlegen " und " Auswahlstatus nach dem Klicken auf die Benutzerzeile "zu ListView.
Beginnen wir also zuerst mit "Auswahl merken" . Das Problem ist, dass Sie das selbst dann tun, wenn Sie das wissen Sie können selector xml verwenden, um highlight / pressed / focus style zu definieren. Aber dieser Stil wird nicht wird beibehalten, nachdem der Benutzer auf diese Zeile geklickt hat. Zum Beispiel habe ich eine Hervorhebung Selektor xml (list_selector.xml unter Res / Zeichnungsordner) wie diese (aber Sie müssen möglicherweise andere Felder wie Textfarbe der Textansicht in Zeile markieren):
%Vor%und list_selector_pressed.xml, die den Hervorhebungsstil definiert haben - legen Sie die Hintergrundfarbe fest zu einer grauen Farbe:
%Vor%So wie @David Hedlund vorgeschlagen hat:
Ordnen Sie stattdessen einen OnItemClickListener zu, und speichern Sie die ID des ausgewählten Elements in einer Variablen.
Sie müssen eine Instanzvariable über Ihrer Klasse erstellen:
%Vor%gehe dann zu
%Vor%Ganz einfach: Wir überprüfen, ob currentSelectedView null ist oder die aktuelle Ansicht geklickt hat oder nicht. Wir heben zuerst jeden Stil auf, indem wir die Methode unhighlightCurrentRow aufrufen (currentSelectedView) --- Sie fragen sich vielleicht, warum wir die momentane Variable currentSelectedView als Parameter übergeben, ich werde es später erklären. Dann weisen wir currentSelectedView eine Ansicht zu und markieren die aktuelle Zeile; damit der Stil beibehalten wird, nachdem der Benutzer geklickt hat.
%Vor%Aha, das ist es. So implementieren wir "remember selection" für die Listenansicht. Wie du siehst, wir müssen die Codes für das Styling sowohl in XML als auch in Java code duplizieren - ziemlich dumm: (
Weiter über "Standardauswahl festlegen" . Sie können denken, dass Sie dies tun können
%Vor% in onCreate () in Aktivität oder onActivityCreated () in Fragment.
Aber wenn Sie es ausführen, erhalten Sie NullPointer-Ausnahme und warum?
Denn zu diesem Zeitpunkt ist die Listenansicht noch nicht gerendert und Android mag kein iOS mit viewWillAppear. Also müssen Sie eine Instant-Variable erstellen, um sich daran zu erinnern, ob die Listview-Zelle zum ersten Mal gerendert wird, und in onListItemClick, um diese Variable zu löschen:
Also unter currentSelectedView Deklaration:
%Vor%Fügen Sie dann Methoden hinzu: Angenommen, wir möchten die erste Zeile in der Listenansicht hervorheben:
%Vor%Ziemlich einfach. Aber Sie müssen einige Änderungen in der onListItemClick-Methode vornehmen:
%Vor%Na los! Viel Spaß mit Android:)
setSelection()
verwenden.
Ich habe das Problem gelöst, indem ich eine Nachricht nach notifyDataSetChanged() ;
gesendet habe und setSelection(0)
in meiner handleMessage-Funktion aufgerufen habe. Es
Scheint hässlich, aber half mir mehrmals, wenn SDK sich seltsam verhält.
Eine viel sauberere Lösung für mich bestand darin, dass, wenn Sie entweder android:choiceMode="singleChoice"
oder android:choiceMode="multipleChoice"
in Ihrer ListView
setzen, ListView
versucht, den aktivierten Status für eine einzelne oder mehrere Selektionen beizubehalten %Code%. Das hängt damit zusammen, dass es von der Listenzelle abhängt, die ListView
Sie beginnen also mit der Implementierung von Checkable
(oder CheckableLinearLayout
könnte besser sein), so dass Android den Status "überprüft" für Sie behält und Sie die Drawable synchron halten können. Der Schlüssel hier ist FrameLayout
und refreshDrawableState
Sie aktualisieren die Drawable, so dass der Hintergrund markiert markiert wird oder nicht.
Dann wird eine einfache onCreateDrawableState
für den Hintergrund, der den Checked-Zustand anzeigt, gezeichnet:
Jetzt kann CheckableLinearLayout in jeder Liste verwendet werden, in der der persistente Auswahlzustand (mehrere oder einzelne) angezeigt werden soll:
%Vor% Ich brauche keinen speziellen Code in selector
, um den aktivierten Status zu aktualisieren, und ich kann die ausgewählte Position um die Rotation herum mit:
und
%Vor% Ebenso kann ich Fragment
verwenden, um ein ursprünglich ausgewähltes Element festzulegen, oder setItemChecked
(oder getCheckedItemPosition
für Mehrfachauswahl), um die aktuelle Auswahl zu erhalten.
Ich verwende einen Adapter und wollte keine benutzerdefinierten Hintergrundfarben einstellen, sondern benutze das android: state_selected in drawable xml. SetSelection funktionierte nicht für mich, aber vielleicht auch, weil ich SetNotifyDataChanged brauchte, was zeigt, dass der ausgewählte Status nicht persistent ist.
Ich habe auch festgestellt, dass der Selected-Status für ein Element in einer ListView nicht persistent ist, da SetNotifyDataChanged dazu führt, dass das ListView-Layout aktualisiert wird, wodurch alle gelöscht werden. Das Festlegen des Elements auf Ausgewählt in der GetView des Adapters ist auch zu früh.
Schließlich setze ich den Selected-Status für die Ansicht des ausgewählten Elements, nachdem das Layout der Listenansicht geändert wurde, wenn das LayoutChange-Ereignis ausgelöst wird (in Java wird wahrscheinlich ein OnLayoutChangeListener der ListView angehängt).
Um es wirklich einfach zu machen, speichere ich die Ansicht des ausgewählten Objekts als SelectedItemView des Adapters. Im EventChange-Event-Manager von ListView setze ich SelectedItemView.Selected des Adapters einfach auf true.
Hier ist der Code von meiner Activity, wo ich den Adapter für die ListView gesetzt habe und auch ein LayoutChange abonniere (oder in Java einen OnLayoutChangeListener)
%Vor%Hier ist mein Code für den Adapter:
%Vor%Tags und Links android