Ok wszyscy wiedzą, że aby ukryć klawiaturę, musisz zaimplementować:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
Ale najważniejsze jest to, jak ukryć klawiaturę, gdy użytkownik dotyka lub wybiera inne miejsce, które nie jest klawiaturą lub klawiaturą EditText
?
Próbowałem użyć onTouchEvent()
na moim rodzicu, Activity
ale to działa tylko wtedy, gdy użytkownik dotyka poza jakimkolwiek innym widokiem i nie ma widoku przewijania.
Próbowałem zaimplementować nasłuchiwanie dotykowe, kliknięcie i skupienie bez powodzenia.
Próbowałem nawet wdrożyć własny widok przewijania, aby przechwytywać zdarzenia dotykowe, ale mogę uzyskać tylko współrzędne zdarzenia, a nie kliknięcie widoku.
Czy istnieje standardowy sposób to zrobić? w iPhonie było to naprawdę łatwe.
android
android-softkeyboard
htafoya
źródło
źródło
getFields()
tutaj: stackoverflow.com/questions/7790487/…Odpowiedzi:
Poniższy fragment kodu po prostu ukrywa klawiaturę:
Możesz umieścić to w klasie użyteczności lub, jeśli definiujesz to w ramach działania, unikaj parametru aktywności lub wywołania
hideSoftKeyboard(this)
.Najtrudniejsze jest, kiedy to nazwać. Możesz napisać metodę, która będzie iterować przez wszystkie
View
działania, i sprawdź, czy jest to metoda,instanceof EditText
jeśli nie jest ona zarejestrowana wsetOnTouchListener
tym komponencie i wszystko się ułoży. Jeśli zastanawiasz się, jak to zrobić, jest to dość proste. Oto, co robisz, piszesz metodę rekurencyjną, taką jak poniżej, w rzeczywistości możesz tego użyć, aby zrobić wszystko, na przykład skonfigurować niestandardowe kroje pisma itp. Oto metodaTo wszystko, po prostu wywołaj tę metodę po tobie
setContentView
w swojej aktywności. Jeśli zastanawiasz się, jaki parametr chcesz przekazać, jest toid
kontener nadrzędny. Przypiszid
do swojego nadrzędnego kontenera jak<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>
i zadzwoń
setupUI(findViewById(R.id.parent))
, to wszystko.Jeśli chcesz efektywnie z tego korzystać, możesz utworzyć metodę rozszerzoną
Activity
i wprowadzić tę metodę, a wszystkie inne działania w aplikacji rozszerzyć tę aktywność i wywołać jąsetupUI()
wonCreate()
metodzie.Mam nadzieję, że to pomoże.
Jeśli używasz więcej niż 1 działania, zdefiniuj wspólny identyfikator układu nadrzędnego, np
<RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Następnie rozszerz klasę
Activity
i zdefiniuj wsetupUI(findViewById(R.id.main_parent))
jej obrębieOnResume()
i rozszerz tę klasę zamiast `` Aktywnośćin your program
Oto wersja powyższej funkcji Kotlin:
źródło
if(activity.getCurrentFocus() != null) {...}
OnTouchListener
dla nich ustawiać . Możesz po prostu ustawić tę logikę wViewGroup.onInterceptTouchEvent(MotionEvent)
widoku głównym.Możesz to osiągnąć, wykonując następujące czynności:
Ustaw widok nadrzędny (widok zawartości Twojej aktywności), na który można kliknąć, i można go ustawić, dodając następujące atrybuty
Zaimplementuj metodę hideKeyboard ()
Na koniec ustaw onFocusChangeListener swojego tekstu edytującego.
Jak wskazano w jednym z poniższych komentarzy, może to nie działać, jeśli widok nadrzędny jest ScrollView. W takim przypadku klikalny i możliwy do ustawienia obiektInTouchMode można dodać w widoku bezpośrednio pod ScrollView.
źródło
clickable
ifocusableInTouchMode
do mojegoScrollView
elementu głównego . Musiałem dodać do bezpośredniego rodzica mojego,EditText
który byłLinearLayout
.Po prostu zastąp kod poniżej w Aktywności
źródło
Uważam, że zaakceptowana odpowiedź jest nieco skomplikowana.
Oto moje rozwiązanie. Dodaj
OnTouchListener
do głównego układu, tj .:i umieść następujący kod w metodzie onTouch.
W ten sposób nie musisz powtarzać wszystkich widoków.
źródło
android:onClick="stealFocusFromEditTexts"
Do xml widoku rodzica, a następniepublic void stealFocusFromEditTexts(View view) {}
do jego aktywności. Metoda „kliknięcie” nie musi nic robić, musi istnieć, aby widok nadrzędny mógł być aktywny / możliwy do wybrania, co jest konieczne do kradzieży fokusu z dziecka EditTextMam jeszcze jedno rozwiązanie, aby ukryć klawiaturę:
Tutaj przechodzą
HIDE_IMPLICIT_ONLY
w pozycjishowFlag
i0
w pozycjihiddenFlag
. Mocno zamknie miękką klawiaturę.źródło
Cóż, udaje mi się nieco rozwiązać problem, przesłoniłem dispatchTouchEvent w mojej działalności, tam używam następujących poleceń, aby ukryć klawiaturę.
EDYCJA: Metoda getFields () jest po prostu metodą zwracającą tablicę z polami tekstowymi w widoku. Aby uniknąć tworzenia tej tablicy za każdym dotknięciem, stworzyłem tablicę statyczną o nazwie sFields, która jest zwracana przy użyciu metody getFields (). Ta tablica jest inicjowana w metodach onStart (), takich jak:
sFields = new EditText[] {mUserField, mPasswordField};
To nie jest idealne, czas zdarzenia przeciągania jest oparty tylko na heurystyce, więc czasami nie ukrywa się podczas wykonywania długich kliknięć, a także zakończyłem, tworząc metodę, aby uzyskać wszystkie editTexts na widok; w przeciwnym razie klawiatura ukryłaby się i pokazała po kliknięciu innego przycisku EditText.
Mimo to mile widziane są czystsze i krótsze rozwiązania
źródło
getFields()
metodę? Nie musi to być dokładne, tylko przykład z być może tylko komentarzami wskazującymi, że zwraca tablicęEditText
obiektów.Użyj OnFocusChangeListener .
Na przykład:
Aktualizacja : możesz również zastąpić
onTouchEvent()
swoją aktywność i sprawdzić współrzędne dotyku. Jeśli współrzędne znajdują się poza EditText, ukryj klawiaturę.źródło
Zaimplementowałem dispatchTouchEvent w działaniu, aby to zrobić:
i przetestowałem to, działa idealnie!
źródło
Bardziej Kotlin i materiał do projektowania materiałów za pomocą TextInputEditText (to podejście jest również kompatybilne z EditTextView ) ...
1. Spraw, aby widok nadrzędny (widok zawartości Twojej aktywności / fragmentu) był klikalny i można go ustawić, dodając następujące atrybuty
2. Utwórz rozszerzenie dla wszystkich widoków (na przykład w pliku ViewExtension.kt):
3. Utwórz BaseTextInputEditText, który odziedziczy TextInputEditText. Zaimplementuj metodę onFocusChanged, aby ukryć klawiaturę, gdy widok nie jest skupiony:
4. Po prostu nazwij swój nowy niestandardowy widok w swoim XML:
To wszystko. Nie trzeba modyfikować kontrolerów (fragmentu lub działania), aby obsłużyć ten powtarzalny przypadek.
źródło
Zastąp publiczny logiczny dispatchTouchEvent (zdarzenie MotionEvent) w dowolnym działaniu (lub rozszerz klasę działania)
I to wszystko, co musisz zrobić
źródło
Zmodyfikowałem rozwiązanie Andre Luis IM. Osiągnąłem to:
Stworzyłem metodę narzędzia do ukrywania miękkiej klawiatury w taki sam sposób, jak Andre Luiz IM:
Ale zamiast rejestrować OnTouchListener dla każdego widoku, który daje słabą wydajność, zarejestrowałem OnTouchListener tylko dla widoku głównego. Ponieważ zdarzenie bąbelkuje, dopóki nie zostanie zużyte (EditText jest jednym z widoków, który zużywa go domyślnie), jeśli dojdzie do widoku głównego, dzieje się tak, ponieważ nie został zużyty, więc zamykam miękką klawiaturę.
źródło
Zdaję sobie sprawę, że ten wątek jest dość stary, poprawna odpowiedź wydaje się ważna i istnieje wiele działających rozwiązań, ale myślę, że podane poniżej podejście może mieć dodatkową korzyść w zakresie wydajności i elegancji.
Potrzebuję tego zachowania do wszystkich moich działań, więc utworzyłem klasę CustomActivity dziedziczącą z klasy Activity i „zaczepiłem” funkcję dispatchTouchEvent . Należy przede wszystkim spełnić dwa warunki:
Oto mój wynik:
Uwaga dodatkowa: Dodatkowo przypisuję te atrybuty do widoku głównego, dzięki czemu można wyczyścić fokus na każdym polu wejściowym i zapobiec skupianiu się pól wejściowych na uruchamianiu aktywności (dzięki czemu widok zawartości jest „łapaczem fokusu”):
źródło
Podobało mi się podejście do dzwonienia
dispatchTouchEvent
wykonane przez htafoya, ale:Uczyniłem to nieco łatwiejszym rozwiązaniem:
Jest jedna wada:
Przejście z jednego
EditText
do drugiegoEditText
czyni skórę klawiatury i reshow - w moim przypadku jest to pożądane w ten sposób, ponieważ pokazuje, że przełączane pomiędzy dwoma składnikami wejściowych.źródło
Zarzut: Rozumiem, że nie mam siły przebicia, ale proszę, potraktuj poważnie moją odpowiedź.
Problem: Wyłącz klawiaturę miękką, gdy klikasz poza klawiaturę lub edytujesz tekst z minimalnym kodem.
Rozwiązanie: zewnętrzna biblioteka znana jako Butterknife.
Rozwiązanie jednoliniowe:
Bardziej czytelne rozwiązanie:
Objaśnienie: Powiąż odbiornik OnClick z identyfikatorem nadrzędnym układu XML działania, aby każde kliknięcie układu (nie dotyczy tekstu edycji ani klawiatury) spowodowało uruchomienie tego fragmentu kodu, który ukryje klawiaturę.
Przykład: jeśli plik układu to R.layout.my_layout, a identyfikator układu to R.id.my_layout_id, wówczas wywołanie powiązania Butterknife powinno wyglądać następująco:
Link do dokumentacji Butterknife: http://jakewharton.github.io/butterknife/
Wtyczka: Butterknife zrewolucjonizuje Twój rozwój Androida. Rozważ to.
Uwaga: Ten sam wynik można osiągnąć bez użycia zewnętrznej biblioteki Butterknife. Wystarczy ustawić OnClickListener na układ nadrzędny, jak opisano powyżej.
źródło
W kotlin możemy wykonać następujące czynności. Nie ma potrzeby powtarzania wszystkich widoków. Będzie działać również w przypadku fragmentów.
źródło
Oto kolejna odmiana odpowiedzi Fje, która dotyczy problemów podniesionych przez sosite.
Chodzi o to, aby poradzić sobie zarówno z działaniami w dół, jak i w górę w działaniu
dispatchTouchEvent
metodzie działania. Podczas akcji „w dół” odnotowujemy aktualnie skupiony widok (jeśli istnieje) i to, czy był w nim dotyk, zapisując oba te fragmenty informacji na później.Jeśli chodzi o akcję up, najpierw wysyłamy, aby umożliwić inny widok potencjalnie skupić się. Jeśli po tym, aktualnie skupiony widok jest pierwotnie skupionym widokiem, a dolny dotyk był w tym widoku, to zostawiamy klawiaturę otwartą.
Jeśli aktualnie ustawiony widok jest inny niż pierwotnie ustawiony widok i jest to
EditText
, pozostawiamy również klawiaturę otwartą.W przeciwnym razie zamykamy to.
Podsumowując, działa to w następujący sposób:
EditText
klawiatury pozostaje otwartaEditText
na innyEditText
klawiatura pozostaje otwarta (nie zamyka się / nie otwiera ponownie)EditText
który nie jest innyEditText
, klawiatura zamyka sięEditText
aby wyświetlić kontekstowy pasek akcji (z przyciskami wycinania / kopiowania / wklejania), klawiatura pozostaje otwarta, nawet jeśli akcja UP miała miejsce poza aktywnymEditText
(który przesunął się w dół, aby zrobić miejsce dla CAB) . Pamiętaj jednak, że naciśnięcie przycisku w CAB spowoduje zamknięcie klawiatury. To może, ale nie musi być pożądane; jeśli chcesz wyciąć / skopiować z jednego pola i wkleić do innego, byłoby to możliwe. Jeśli chcesz wkleić z powrotem w to samoEditText
, nie byłoby.gdy fokus
EditText
znajduje się na dole ekranu i długo klikasz tekst, aby go zaznaczyć,EditText
utrzymuje fokus, a zatem klawiatura otwiera się tak, jak chcesz, ponieważ wykonujemy sprawdzanie „dotyk jest w granicach widoku” podczas akcji w dół , a nie wzrost akcji.źródło
jest to zbyt proste, po prostu ustaw swój układ, który można kliknąć, aby można go było ustawić za pomocą tego kodu:
a następnie napisz metodę i OnClickListner dla tego układu, aby po dotknięciu najwyższego układu w dowolnym miejscu wywołał metodę, w której napiszesz kod, aby zamknąć klawiaturę. następuje kod obu; // musisz to napisać w OnCreate ()
metoda wywoływana z listnera: -
źródło
Uważam, że zaakceptowana bitowa odpowiedź jest złożona dla tego prostego wymagania. Oto, co zadziałało dla mnie bez żadnych problemów.
źródło
NestedScrollView
lub złożonych układów, zapoznaj się z przyjętą odpowiedzią: stackoverflow.com/a/11656129/2914140 . Powinieneś wiedzieć, że inne pojemniki mogą powodować uszkodzenia.Istnieje prostsze podejście, oparte na tym samym problemie iPhone'a. Wystarczy zastąpić układ tła na zdarzeniu dotykowym, w którym znajduje się edytowany tekst. Wystarczy użyć tego kodu w OnCreate działania (login_fondo to układ główny):
źródło
Metoda pokazywania / ukrywania miękkiej klawiatury
Mam nadzieję, że były przydatne
źródło
To jest dla mnie najłatwiejsze rozwiązanie (i opracowane przeze mnie).
Jest to metoda na ukrycie klawiatury.
teraz ustaw atrybut onclick nadrzędnego układu działania na powyższą metodę
hideKeyboard
albo z widoku Projekt pliku XML lub pisząc poniższy kod w widoku Tekst pliku XML.źródło
Udoskonaliłem metodę, umieściłem następujący kod w pewnej klasie narzędzi interfejsu użytkownika (najlepiej niekoniecznie), aby można było uzyskać do niego dostęp ze wszystkich klas Activity lub Fragment, aby spełniał swoje zadanie.
Powiedz na przykład, że musisz wywołać to z aktywności, nazwij to w następujący sposób;
Ogłoszenie
To daje nam widok główny bieżącej grupy (nie możesz ustawić identyfikatora w widoku głównym).
Twoje zdrowie :)
źródło
Spróbuj ustawić stateHidden jako swoją aktywność
windowSoftInputMode
wartośćhttp://developer.android.com/reference/android/R.attr.html#windowSoftInputMode
Na przykład dla Twojej aktywności:
źródło
Czynność
ScreenUtils
źródło
Po prostu dodaj ten kod do klasy @Overide
źródło
Zamiast iterować wszystkie widoki lub nadpisywać dispatchTouchEvent.
Dlaczego po prostu nie zastąpić onUserInteraction () działania, upewni się, że klawiatura zostanie zwolniona za każdym razem, gdy użytkownik stuknie poza EditText.
Działa nawet wtedy, gdy EditText znajduje się w scrollView.
źródło
Dostałem to z niewielkim wariantem rozwiązania Fernando Camarago. W metodzie onCreate dołączam pojedynczy widok onTouchListener do widoku głównego, ale przesyłam widok zamiast działania jako argument.
W osobnej klasie Utils jest ...
źródło
To może być stare, ale udało mi się to zaimplementować niestandardową klasę
najlepszą praktyką jest tutaj stworzenie klasy Pomocnika, a każdy kontener Względny / Liniowy Układ powinien to zaimplementować.
**** Uwaga: tylko główny kontener powinien implementować tę klasę (dla optymalizacji) ****
i zaimplementuj to w następujący sposób:
to słowo kluczowe dla Aktywności. więc jeśli jesteś na fragmencie, używasz jak getActivity ();
--- kciuki do góry, jeśli ci to pomoże ... --- na zdrowie Ralph ---
źródło
To jest nieco zmodyfikowana wersja odpowiedzi fje, która w większości działała idealnie.
Ta wersja używa ACTION_DOWN, więc wykonanie operacji przewijania również zamyka klawiaturę. Nie propaguje również zdarzenia, chyba że klikniesz inny EditText. Oznacza to, że kliknięcie w dowolnym miejscu poza tekstem edycji, nawet w innym klikalnym, po prostu zamyka klawiaturę.
źródło
view
iviewTmp
dogetCurrentFocus()
, więc oni zawsze będzie ta sama wartość.Zrobiłem w ten sposób:
Ukryj kod klawiatury :
Gotowy
źródło