Do tej pory spędziłem nad tym około 6 godzin i uderzałem tylko w blokady drogowe. Ogólne założenie jest takie, że istnieje wiersz ListView
(niezależnie od tego, czy został wygenerowany przez adapter, czy dodany jako widok nagłówka), który zawiera EditText
widget i plik Button
. Chcę tylko móc użyć kulki / strzałek, aby przejść selektorem do poszczególnych elementów, tak jak zwykle, ale kiedy dojdę do określonego wiersza - nawet jeśli muszę wyraźnie zidentyfikować wiersz - ma on opcję fokusu dziecko, chcę, aby dziecko skupiło się, zamiast wskazywać pozycję za pomocą selektora.
Wypróbowałem wiele możliwości i do tej pory nie miałem szczęścia.
układ:
<ListView
android:id="@android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Widok nagłówka:
EditText view = new EditText(this);
listView.addHeaderView(view, null, true);
Zakładając, że w adapterze znajdują się inne pozycje, użycie klawiszy strzałek spowoduje przesunięcie wyboru w górę / w dół listy zgodnie z oczekiwaniami; ale kiedy przechodzimy do wiersza nagłówka, jest on również wyświetlany za pomocą selektora i nie ma możliwości skupienia się na EditText
używaniu kulki. Uwaga: dotknięcie przycisku EditText
spowoduje skupienie się w tym momencie, jednak zależy to od ekranu dotykowego, co nie powinno być wymagane.
ListView
najwyraźniej ma dwa tryby w tym względzie:
1 setItemsCanFocus(true)
.: selektor nigdy nie jest wyświetlany, ale EditText
może uzyskać ostrość, gdy używasz strzałek. Algorytm wyszukiwania fokusowego jest trudny do przewidzenia i nie ma wizualnej informacji zwrotnej (w jakimkolwiek wierszu: z wybranymi elementami podrzędnymi lub nie), z których oba mogą dać użytkownikowi nieoczekiwane wrażenia.
2.setItemsCanFocus(false)
.: Selektor jest zawsze rysowany w trybie bezdotykowym i EditText
nigdy nie może uzyskać ostrości - nawet jeśli go dotkniesz.
Co gorsza, dzwonię editTextView.requestFocus()
zwraca prawdę, ale w rzeczywistości nie skupia się na EditText.
To, co wyobrażam, jest w zasadzie hybrydą 1 i 2, gdzie zamiast ustawienia listy, czy wszystkie elementy są aktywne, czy nie, chcę ustawić ostrość dla jednego elementu na liście, tak aby selektor płynnie przechodził od wyboru cały wiersz dla elementów, na które nie można skupić się, i przechodzenie przez drzewo aktywności dla elementów, które zawierają elementy podrzędne, na które można ustawić fokus.
Jacyś chętni?
descendantFocusability="afterDescendants"
pozwoli na EditText wziąć ostrość wewnątrz ListView, ale potem masz żadnego wyboru elementu listy podczas nawigowania z padu kierunkowego. Moim zadaniem było umieszczenie selektora elementów listy we wszystkich wierszach oprócz tego z EditText. Cieszę się, że to pomogło. FWIW, w końcu ponownie oceniliśmy tę implementację i zdecydowaliśmy, że element, na którym można skupić się w ListView, nie jest po prostu idiomatycznym projektem interfejsu użytkownika systemu Android, więc porzuciliśmy ten pomysł na rzecz podejścia bardziej przyjaznego dla systemu Android.To mi pomogło.
W twoim manifeście:
źródło
OnItemSelectedListener
nie zmienia tego. Jednak proste rozwiązanie Iogana działa jak urok, dzięki!android:descendantFocusability
własność got myEditText
s wewnątrzListView
rozwiązywania klawiaturę poprawnie, upvoted obu.android:descendantFocusability
samo w sobie nie wystarczyło i nie byłem entuzjastycznie nastawiony@Overriding
onItemSelected
do wszystkich 14EditText
sekund, z którymi mam do czynienia. :) Dzięki!Moim zadaniem było wdrożenie,
ListView
które rozszerza się po kliknięciu. Dodatkowe miejsce pokazuje,EditText
gdzie można wprowadzić tekst. Aplikacja powinna działać w wersji 2.2+ (do 4.2.2 w momencie pisania tego)Wypróbowałem wiele rozwiązań z tego postu i innych, które mogłem znaleźć; przetestowałem je na urządzeniach od 2.2 do 4.2.2. Żadne z rozwiązań nie było satysfakcjonujące na wszystkich urządzeniach 2.2+, każde rozwiązanie prezentowało inne problemy.
Chciałem podzielić się moim ostatecznym rozwiązaniem:
android:descendantFocusability="afterDescendants"
setItemsCanFocus(true);
android:windowSoftInputMode="adjustResize"
Wiele osób sugeruje,adjustPan
aleadjustResize
daje znacznie lepsze ux imho, po prostu przetestuj to w swoim przypadku. ZadjustPan
uzyskasz na przykład zasłonięte dolne pozycje z listy. Dokumenty sugerują, że („Generalnie jest to mniej pożądane niż zmiana rozmiaru”). Również w 4.0.4, gdy użytkownik zacznie pisać na klawiaturze ekranowej, ekran przesunie się do góry.adjustResize
problemami z fokusem EditText. Rozwiązaniem jest zastosowanie rozwiązania rjrjr z tego wątku. Wygląda strasznie, ale tak nie jest. I to działa. Po prostu spróbuj.Dodatkowe 5. Ze względu na odświeżanie adaptera (z powodu zmiany rozmiaru widoku), gdy
EditText
zyski skupiają się na wersjach wcześniejszych niż HoneyComb, znalazłem problem z odwróconymi widokami: pobieranie widoku elementu ListView / odwrócenie kolejności w wersji 2.2; działa na 4.0.3Jeśli wykonujesz jakieś animacje, możesz chcieć zmienić zachowanie na
adjustPan
wersje wcześniejsze niż plaster miodu, aby funkcja zmiany rozmiaru nie uruchamiała się, a adapter nie odświeżał widoków. Musisz tylko dodać coś takiegoWszystko to daje akceptowalny UX na urządzeniach 2.2 - 4.2.2. Mam nadzieję, że zaoszczędzi to ludziom trochę czasu, ponieważ dojście do tego wniosku zajęło mi co najmniej kilka godzin.
źródło
To uratowało mi życie --->
ustaw tę linię
ListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Następnie w swoim manifeście w tagu aktywności wpisz to ->
<activity android:windowSoftInputMode="adjustPan">
Twój zwykły zamiar
źródło
Próbujemy tego na krótkiej liście, która nie przewiduje recyklingu. Na razie w porządku.
XML:
Jawa:
źródło
ten post pasował dokładnie do moich słów kluczowych. Mam nagłówek ListView z wyszukiwaniem EditText i przyciskiem wyszukiwania.
Aby skupić się na EditText po utracie początkowego fokusu, jedyne HACK, które znalazłem, to:
Straciłem wiele godzin i to nie jest prawdziwa poprawka. Mam nadzieję, że pomoże to komuś twardemu.
źródło
Jeśli lista jest dynamiczna i zawiera widżety, na które można ustawić fokus, właściwą opcją jest użycie RecyclerView zamiast ListView IMO.
Do obejścia że zestaw
adjustPan
,FOCUS_AFTER_DESCENDANTS
lub ręcznie pamiętają skoncentrowaną pozycję, rzeczywiście są tylko rozwiązania. Mają narożne przypadki (przewijanie + problemy z klawiaturą miękką, zmiana pozycji kursora w EditText). Nie zmienia to faktu, że ListView tworzy / niszczy widoki masowo czasienotifyDataSetChanged
.Dzięki RecyclerView powiadamiasz o poszczególnych wstawieniach, aktualizacjach i usunięciach. Widok skupiony nie jest odtwarzany, więc nie ma problemów z utratą aktywności kontrolek formularza. Jako dodatkowy bonus, RecyclerView animuje wstawianie i usuwanie elementów listy.
Oto przykład z oficjalnej dokumentacji, jak zacząć
RecyclerView
: Przewodnik dla programistów - Utwórz listę za pomocą RecyclerViewźródło
Czasami, gdy używasz
android:windowSoftInputMode="stateAlwaysHidden"
w manifest activity lub xml, tym razem stracisz fokus klawiatury. Więc najpierw sprawdź tę właściwość w swoim xml i manifeście, jeśli tam jest, po prostu ją usuń. Po dodaniu tych opcji, aby zamanifestować plik w działaniu pobocznymandroid:windowSoftInputMode="adjustPan"
i dodać tę właściwość do widoku listy w formacie xmlandroid:descendantFocusability="beforeDescendants"
źródło
Innym prostym rozwiązaniem jest zdefiniowanie onClickListener w metodzie getView (..) Twojego ListAdapter.
W ten sposób można kliknąć wiersz, a także widok wewnętrzny :)
źródło
Najważniejsze jest, aby fokus działał dla komórki listy. Szczególnie w przypadku listy w Google TV jest to niezbędne:
Metoda setItemsCanFocus widoku listy załatwia sprawę :
Moja komórka listy xml zaczyna się następująco:
nextFocusLeft / Right są również ważne dla nawigacji D-Pad.
Aby uzyskać więcej informacji, zapoznaj się z innymi świetnymi odpowiedziami.
źródło
Właśnie znalazłem inne rozwiązanie. Uważam, że to bardziej hack niż rozwiązanie, ale działa na Androidzie 2.3.7 i Androidzie 4.3 (testowałem nawet tego starego dobrego D-pad)
init your webview jak zwykle i dodaj to: (dzięki Michael Bierman)
Podczas połączenia getView:
źródło
Po prostu spróbuj tego
w
sekcja manifestu. Tak, nie dostosowuje niczego, co oznacza, że editText pozostanie tam, gdzie jest, gdy jest otwierany IME. Ale to tylko mała niedogodność, która nadal całkowicie rozwiązuje problem utraty koncentracji.
źródło