Ich habe bisher ungefähr 6 Stunden damit verbracht und nichts als Straßensperren getroffen. Die allgemeine Voraussetzung ist, dass eine Zeile ListView
(unabhängig davon, ob sie vom Adapter generiert oder als Header-Ansicht hinzugefügt wird) eine Zeile enthält, die ein EditText
Widget und ein enthält Button
. Alles, was ich tun möchte, ist, den Jogball / die Pfeile verwenden zu können, um den Selektor wie gewohnt zu einzelnen Elementen zu navigieren, aber wenn ich zu einer bestimmten Zeile komme - auch wenn ich die Zeile explizit identifizieren muss -, hat dies eine Fokussierbarkeit Kind, ich möchte, dass dieses Kind den Fokus erhält, anstatt die Position mit dem Selektor anzuzeigen.
Ich habe viele Möglichkeiten ausprobiert und bisher kein Glück gehabt.
Layout:
<ListView
android:id="@android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Kopfansicht:
EditText view = new EditText(this);
listView.addHeaderView(view, null, true);
Angenommen, der Adapter enthält weitere Elemente. Mit den Pfeiltasten wird die Auswahl in der Liste erwartungsgemäß nach oben / unten verschoben. Wenn Sie jedoch zur Kopfzeile gelangen, wird diese auch mit dem Selektor angezeigt, und Sie können sich nicht auf die EditText
Verwendung des Jogballs konzentrieren. Hinweis: Wenn Sie auf das tippen, EditText
wird es an diesem Punkt fokussiert. Dies hängt jedoch von einem Touchscreen ab, der nicht erforderlich sein sollte.
ListView
Anscheinend gibt es diesbezüglich zwei Modi:
1 . setItemsCanFocus(true)
: Der Selektor wird nie angezeigt, aber der EditText
kann bei Verwendung der Pfeile scharfgestellt werden. Der Fokus-Suchalgorithmus ist schwer vorherzusagen und es gibt kein visuelles Feedback (zu Zeilen: mit fokussierbaren untergeordneten Elementen oder nicht), welches Element ausgewählt ist. Beides kann dem Benutzer eine unerwartete Erfahrung bieten.
2 . setItemsCanFocus(false)
: Der Selektor wird immer im Non-Touch-Modus gezeichnet und EditText
kann niemals scharfgestellt werden - selbst wenn Sie darauf tippen.
Um die Sache noch schlimmer zu machen, gibt der Aufruf editTextView.requestFocus()
true zurück, gibt jedoch nicht den EditText-Fokus.
Was ich mir vorstelle, ist im Grunde eine Mischung aus 1 und 2, bei der ich anstelle der Listeneinstellung, ob alle Elemente fokussierbar sind oder nicht, die Fokussierbarkeit für ein einzelnes Element in der Liste festlegen möchte , damit der Selektor nahtlos von der Auswahl der Elemente abweicht ganze Zeile für nicht fokussierbare Elemente und Durchlaufen des Fokusbaums für Elemente, die fokussierbare untergeordnete Elemente enthalten.
Irgendwelche Abnehmer?
descendantFocusability="afterDescendants"
Ihr EditText kann sich auf die ListView konzentrieren, aber dann erhalten Sie beim Navigieren mit einem dpad keine Auswahl für Listenelemente. Meine Aufgabe war es, die Listenelementauswahl in allen Zeilen außer der mit dem EditText zu haben. Ich bin froh, dass es geholfen hat. FWIW, wir haben diese Implementierung letztendlich neu bewertet und entschieden, dass ein fokussierbares Design in einer ListView kein idiomatisches Android-UI-Design ist. Deshalb haben wir die Idee zugunsten eines Android-freundlicheren Ansatzes verworfen.Das hat mir geholfen.
In Ihrem Manifest:
quelle
OnItemSelectedListener
ändert du nicht. Die einfache Lösung von Iogan funktioniert jedoch wie ein Zauber, danke!android:descendantFocusability
Eigenschaft hätte meinenEditText
s innerhalb von einem aufListView
die Tastatur zu lösen richtig, upvoted beide.android:descendantFocusability
an sich hat es nicht geschafft und ich war nicht im entferntesten begeistert von@Overriding
onItemSelected
allen 14EditText
Sekunden, mit denen ich zu tun habe. :) Vielen Dank!Meine Aufgabe war es zu implementieren,
ListView
was sich beim Klicken erweitert. Der zusätzliche Bereich zeigt an,EditText
wo Sie Text eingeben können. Die App sollte ab Version 2.2 funktionsfähig sein (bis zu 4.2.2 zum Zeitpunkt des Schreibens)Ich habe zahlreiche Lösungen aus diesem Beitrag und anderen, die ich finden konnte, ausprobiert. testete sie auf 2.2 bis 4.2.2 Geräten. Keine der Lösungen war auf allen Geräten ab Version 2.2 zufriedenstellend, wobei jede Lösung unterschiedliche Probleme aufwies.
Ich wollte meine endgültige Lösung teilen:
android:descendantFocusability="afterDescendants"
setItemsCanFocus(true);
android:windowSoftInputMode="adjustResize"
Viele Leute schlagen voradjustPan
,adjustResize
geben aber viel besseres ux imho, testen Sie dies einfach in Ihrem Fall. MitadjustPan
Sie beispielsweise unterste Listenelemente, die verdeckt sind. Die Dokumente schlagen vor, dass ("Dies ist im Allgemeinen weniger wünschenswert als die Größenänderung"). Ebenfalls in 4.0.4, nachdem der Benutzer mit der Eingabe auf der Softtastatur begonnen hat, wird der Bildschirm nach oben verschoben.adjustResize
gibt es einige Probleme mit dem EditText-Fokus. Die Lösung besteht darin, die rjrjr-Lösung aus diesem Thread anzuwenden. Es sieht beängstigend aus, ist es aber nicht. Und es funktioniert. Probier es einfach.Zusätzliche 5. Aufgrund der
EditText
Aktualisierung des Adapters (aufgrund der Größenänderung der Ansicht), wenn der Fokus auf frühere HoneyComb-Versionen gelegt wird, trat ein Problem mit umgekehrten Ansichten auf: Abrufen der Ansicht für ListView-Element / umgekehrte Reihenfolge in 2.2; funktioniert am 4.0.3Wenn Sie einige Animationen
adjustPan
ausführen, möchten Sie möglicherweise das Verhalten für Versionen vor der Wabe ändern, damit die Größenänderung nicht ausgelöst wird und der Adapter die Ansichten nicht aktualisiert. Sie müssen nur so etwas hinzufügenAll dies ergibt einen akzeptablen UX auf 2.2 - 4.2.2 Geräten. Ich hoffe, es wird den Menschen Zeit sparen, da ich mindestens einige Stunden gebraucht habe, um zu diesem Schluss zu kommen.
quelle
Das hat mir das Leben gerettet --->
setze diese Zeile
ListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Geben Sie dann in Ihrem Manifest im Aktivitäts-Tag Folgendes ein ->
<activity android:windowSoftInputMode="adjustPan">
Deine übliche Absicht
quelle
Wir versuchen dies auf einer kurzen Liste, die kein View-Recycling durchführt. So weit, ist es gut.
XML:
Java:
quelle
Dieser Beitrag stimmte genau mit meinen Keywords überein. Ich habe einen ListView-Header mit einem EditText für die Suche und einer Suchschaltfläche.
Um den EditText nach dem Verlieren des anfänglichen Fokus zu fokussieren, habe ich nur Folgendes gefunden:
Viele Stunden verloren und es ist keine echte Lösung. Hoffe es hilft jemandem hart.
quelle
Wenn die Liste dynamisch ist und fokussierbare Widgets enthält, ist die richtige Option zu verwenden RecyclerView anstelle von ListView IMO zu verwenden.
Die Abhilfen , dass Satz
adjustPan
,FOCUS_AFTER_DESCENDANTS
oder manuell fokussierten Position erinnern, sind in der Tat nur Workarounds. Sie haben Eckfälle (Bildlauf + Probleme mit der Softtastatur, Caret-Positionsänderung in EditText). Sie ändern nicht die Tatsache , dass Listview / zerstört Ansichten schafft en masse währendnotifyDataSetChanged
.Mit RecyclerView benachrichtigen Sie über einzelne Einfügungen, Aktualisierungen und Löschungen. Die fokussierte Ansicht wird nicht neu erstellt, sodass keine Probleme mit Formularsteuerelementen den Fokus verlieren. Als zusätzlichen Bonus animiert RecyclerView das Einfügen und Entfernen von Listenelementen.
Hier ist ein Beispiel aus offiziellen Dokumenten, wie Sie beginnen können
RecyclerView
: Entwicklerhandbuch - Erstellen Sie eine Liste mit RecyclerViewquelle
android:windowSoftInputMode="stateAlwaysHidden"
Manchmal, wenn Sie in Manifest-Aktivitäten oder XML verwenden, verliert es diesmal den Tastaturfokus. Suchen Sie also zuerst in Ihrer XML-Datei nach dieser Eigenschaft und manifestieren Sie sie. Wenn sie vorhanden ist, entfernen Sie sie einfach. Nachdem Sie diese Option hinzugefügt haben, um die Datei inandroid:windowSoftInputMode="adjustPan"
der Nebenaktivität zu manifestieren, fügen Sie diese Eigenschaft der Listenansicht in XML hinzuandroid:descendantFocusability="beforeDescendants"
quelle
Eine andere einfache Lösung besteht darin, Ihren onClickListener in der Methode getView (..) Ihres ListAdapters zu definieren.
Auf diese Weise können Sie auf Ihre Zeile klicken und auch auf Ihre innere Ansicht :)
quelle
Der wichtigste Teil ist, den Fokus für die Listenzelle zum Laufen zu bringen. Insbesondere für Listen auf Google TV ist dies wichtig:
Die setItemsCanFocus- Methode der Listenansicht erledigt den Trick:
Meine Listenzelle xml beginnt wie folgt:
nextFocusLeft / Right sind auch wichtig für die D-Pad-Navigation.
Weitere Details finden Sie in den anderen tollen Antworten.
quelle
Ich habe gerade eine andere Lösung gefunden. Ich glaube, es ist eher ein Hack als eine Lösung, aber es funktioniert auf Android 2.3.7 und Android 4.3 (ich habe sogar dieses gute alte D-Pad getestet)
Initiieren Sie Ihre Webansicht wie gewohnt und fügen Sie Folgendes hinzu: (danke Michael Bierman)
Während des getView-Aufrufs:
quelle
Probieren Sie es einfach aus
in dem
Abschnitt Ihres Manifests. Ja, es passt nichts an, was bedeutet, dass der editText dort bleibt, wo er ist, wenn IME geöffnet wird. Aber das ist nur eine kleine Unannehmlichkeit, die das Problem des Fokusverlusts immer noch vollständig löst.
quelle