Muszę zrobić bardzo prostą rzecz - dowiedzieć się, czy pokazana jest klawiatura oprogramowania. Czy to możliwe w Androidzie?
516
Muszę zrobić bardzo prostą rzecz - dowiedzieć się, czy pokazana jest klawiatura oprogramowania. Czy to możliwe w Androidzie?
Odpowiedzi:
NOWA ODPOWIEDŹ dodano 25 stycznia 2012 r
Od czasu napisania poniższej odpowiedzi, ktoś przywiódł mnie do istnienia ViewTreeObserver i przyjaciół, interfejsów API, które czają się w SDK od wersji 1.
Zamiast wymagać niestandardowego typu układu, o wiele prostszym rozwiązaniem jest nadanie
@+id/activityRoot
widokowi głównemu aktywności znanego identyfikatora, powiedzmy , podpięcie GlobalLayoutListener do ViewTreeObserver i stamtąd obliczyć różnicę rozmiaru między katalogiem głównym widoku aktywności a rozmiarem okna:Korzystanie z narzędzia, takiego jak:
Łatwy!
Uwaga: Twoja aplikacja musi ustawić tę flagę w Manifeście Androida, w
android:windowSoftInputMode="adjustResize"
przeciwnym razie powyższe rozwiązanie nie będzie działać.ORYGINALNA ODPOWIEDŹ
Tak, jest to możliwe, ale jest o wiele trudniejsze niż powinno być.
Jeśli muszę się martwić, kiedy klawiatura pojawia się i znika (co jest dość często), to dostosowuję moją klasę układu najwyższego poziomu do tej, która zastępuje
onMeasure()
. Podstawowa logika jest taka, że jeśli układ wypełnia się znacznie mniej niż całkowity obszar okna, prawdopodobnie pojawia się miękka klawiatura.Następnie w klasie aktywności ...
źródło
((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
android.R.id.content
), będziesz w stanie z większą pewnością powiedzieć, żeSystem
zamiast aplikacji zmienia się jej wysokość. Byłoby o wiele bezpieczniej dla zespołu Androida, aby dać nam przerwę i dać nam znać przynajmniej podstawowe rzeczy na temat wejścia SoftKeyboard.heightDiff
zawsze będzie zawierać wysokość paska akcji. W nowej odpowiedzi, która została zignorowana przez testowanie, czy ta wysokość jest większa niż jakaś stała, ale 100 pikseli nie jest wystarczająca dla urządzeń xxhdpi, takich jak Nexus 4. Rozważ przekonwertowanie tej wartości na DP, jeśli naprawdę chcesz użyć tej cholernej pracy - na około.Mam nadzieję, że to komuś pomoże.
Nowa odpowiedź, którą udzielił Reuben Scratton, jest świetna i bardzo wydajna, ale naprawdę działa tylko wtedy, gdy ustawisz parametr windowSoftInputMode na wartość dostosowywania. Jeśli ustawisz opcję adjustPan, nadal nie można wykryć, czy klawiatura jest widoczna za pomocą fragmentu kodu. Aby obejść ten problem, wprowadziłem niewielką modyfikację powyższego kodu.
źródło
TwoDScrollerView
podobnego do stackoverflow.com/a/5224088/530513, chociaż z powiększaniem. Dziecko nie było proste,ImageView
ale układ niestandardowy (rozszerza sięRelativeLayout
), ale mimo ustawienia nie było w stanie wykryć klawiatury przy użyciu zalecanego rozwiązaniaandroid:windowSoftInputMode="adjustResize"
. Dzięki!ActionBar
iActionBarSherlock
. Wielkie dzięki! Nawiasem mówiąc, istnieje metodar.height()
:)heightDiff > root.getRootView().getHeight() / 4
ma dobrą wartość do pracy z urządzeniem o wysokiej rozdzielczości. 100px jest za krótkie. w Nexusie 5 z rozdzielczością 1080x1920, 1920 - (996-75)>? 100 = 999 1920 - (1776–75)>? 100 = 219 // klawiatura jest w Galaxy S2 z rozdzielczością 480x800, 800 - (800-38)>? 100 = 38 800 - (410-38)>? 100 = 428 // klawiatura jest uruchomiona, więc magiczna liczba 100px nie jest wystarczająco dobra.Od zawsze było to związane z komputerem, ale to pytanie jest nadal niewiarygodnie istotne!
Więc wziąłem powyższe odpowiedzi i połączyłem je i udoskonaliłem trochę ...
Pracuje dla mnie :)
UWAGA: Jeśli zauważysz, że DefaultKeyboardDP nie pasuje do twojego urządzenia, zagraj z tą wartością i opublikuj komentarz, aby wszyscy wiedzieli, jaka powinna być wartość ... w końcu otrzymamy prawidłową wartość, która pasuje do wszystkich urządzeń!
Aby uzyskać więcej informacji, sprawdź wdrożenie na Cyborgu
źródło
Przepraszam za późną odpowiedź, ale stworzyłem małą klasę pomocnika do obsługi zdarzeń otwierania / zamykania z powiadamianiem słuchaczy i innych przydatnych rzeczy, być może ktoś uznałby to za pomocne:
Przykład użycia:
źródło
getLastKeyboardHeightInPx()
nie obejmuje wysokości tego rzędu. Czy znasz także sposób, aby wziąć to pod uwagę?Niektóre ulepszenia, aby uniknąć nieprawidłowego wykrycia widoczności miękkiej klawiatury na urządzeniach o wysokiej gęstości:
Próg różnicy wysokości należy zdefiniować jako 128 dp , a nie 128 pikseli .
Zapoznaj się z dokumentacją projektową Google o metrykach i siatce , 48 dp to wygodny rozmiar dla obiektu dotykowego, a 32 dp to minimum dla przycisków. Ogólna miękka klawiatura powinna zawierać 4 rzędy klawiszy, więc minimalna wysokość klawiatury powinna wynosić: 32 dp * 4 = 128 dp , co oznacza, że rozmiar progu powinien być przenoszony na piksele przez pomnożenie gęstości urządzenia. W przypadku urządzeń xxxhdpi (gęstość 4) próg wysokości klawiatury miękkiej powinien wynosić 128 * 4 = 512 pikseli.
Różnica wysokości między widokiem korzenia a jego widocznym obszarem:
wysokość widoku korzenia - wysokość paska stanu - widoczna wysokość ramki = dół widoku korzenia - widoczne dno ramy, ponieważ wysokość paska stanu jest równa górze widocznej ramki widoku korzenia.
źródło
Poświęciłem trochę czasu, aby to rozgryźć ... Uruchomiłem kilka wyjątków CastException, ale zorientowałem się, że możesz zastąpić Cię LinearLayout w layout.xml nazwą klasy.
Lubię to:
W ten sposób nie napotkasz żadnych problemów z rzutowaniem.
... a jeśli nie chcesz tego robić na każdej stronie, zalecamy użycie „MasterPage w Androidzie”. Zobacz link tutaj: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx
źródło
Sprawdzanie wysokości elementów nie jest niezawodne, ponieważ niektóre klawiatury, takie jak WifiKeyboard, mają zerową wysokość.
Zamiast tego możesz użyć wyniku wywołania zwrotnego programów showSoftInput () i hideSoftInput (), aby sprawdzić stan klawiatury. Pełne szczegóły i przykładowy kod na
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
źródło
Chodzi o to, że jeśli chcesz ukryć klawiaturę i jednocześnie sprawdzić stan miękkiego wejścia, skorzystaj z następującego rozwiązania:
Ta metoda zwraca wartość true, jeśli klawiatura była pokazywana przed ukryciem.
źródło
Odkryłem, że kombinacja metody @ Reuben_Scratton i metody @ Yogesh wydaje się działać najlepiej. Połączenie ich metod dałoby coś takiego:
źródło
Możesz obserwować ukrycie klawiatury programowej za pomocą decorView działania.
źródło
Zamiast zakładać kodowanie różnic, zrobiłem coś takiego, ponieważ nie miałem opcji menu w mojej aplikacji.
źródło
Istnieje również rozwiązanie z wstawkami systemowymi, ale działa tylko z
API >= 21
(Android L
). Powiedzmy, że maszBottomNavigationView
, co jest dzieckiemLinearLayout
i musisz go ukryć, gdy wyświetlana jest klawiatura:Wszystko, co musisz zrobić, to rozszerzyć
LinearLayout
w następujący sposób:Chodzi o to, że gdy pokazana jest klawiatura, wstawki systemowe są zmieniane z dość dużą
.bottom
wartością.źródło
Jest ukryta metoda może pomóc w tym
InputMethodManager.getInputMethodWindowVisibleHeight
. Ale nie wiem, dlaczego jest ukryty.źródło
Żadne z tych rozwiązań nie będzie działać dla Lollipop w obecnej postaci. W Lollipop
activityRootView.getRootView().getHeight()
zawiera wysokość paska przycisków, a pomiar widoku nie. Zaadaptowałem najlepsze / najprostsze rozwiązanie powyżej do pracy z Lollipop.źródło
Właśnie napotkałem błąd podczas korzystania z większości powyższych rozwiązań, które sugerują dodanie stałej liczby.
S4 ma wysoką rozdzielczość, co spowodowało, że wysokość paska nawigacji wynosi 100 pikseli, więc moja aplikacja myśli, że klawiatura jest otwarta przez cały czas.
Tak więc po wydaniu wszystkich nowych telefonów wysokiej rozdzielczości uważam, że użycie wartości zakodowanej na stałe nie jest dobrym pomysłem na dłuższą metę.
Lepszym podejściem, które znalazłem po kilku testach na różnych ekranach i urządzeniach, było użycie wartości procentowej. Uzyskaj różnicę między decorView a treścią aplikacji, a następnie sprawdź, jaki jest procent tej różnicy. Ze statystyk, które otrzymałem, większość paska nawigacyjnego (niezależnie od rozmiaru, rozdzielczości itp.) Zajmie od 3% do 5% ekranu. Gdy klawiatura była otwarta, zajmowała od 47% do 55% ekranu.
Podsumowując, moim rozwiązaniem było sprawdzenie, czy różnica jest większa niż 10%, a następnie zakładam, że klawiatura jest otwarta.
źródło
Użyłem niewielkiego wariantu odpowiedzi Reubana, który okazał się bardziej pomocny w pewnych okolicznościach, szczególnie w przypadku urządzeń o wysokiej rozdzielczości.
źródło
R.id.activityRoot
, możesz po prostu użyćandroid.R.id.content
dokładnie tego, czego potrzebujesz.Od zawsze było to związane z komputerem, ale to pytanie jest nadal niewiarygodnie istotne! Więc wziąłem powyższe odpowiedzi i połączyłem je i udoskonaliłem trochę ...
Mi to pasuje.
źródło
Spróbuj tego:
źródło
Moja odpowiedź jest w zasadzie taka sama jak odpowiedź Kachi, ale zapakowałem ją w fajną klasę pomocników, aby wyczyścić sposób, w jaki jest używana w mojej aplikacji.
Możesz użyć tego do wykrywania zmian klawiatury w dowolnym miejscu aplikacji:
Uwaga: używaj tylko jednego z połączeń „rejestruj”. Wszystkie działają tak samo i są dostępne tylko dla wygody
źródło
możesz spróbować tego, działa świetnie dla mnie:
źródło
Miałem trudności z utrzymaniem stanu klawiatury podczas zmiany orientacji fragmentów w przeglądarce. Nie jestem pewien dlaczego, ale wydaje się, że jest nieprzyjemny i działa inaczej niż standardowa aktywność.
Aby w tym przypadku utrzymać stan klawiatury, najpierw dodaj ją
android:windowSoftInputMode = "stateUnchanged"
do swojegoAndroidManifest.xml
. Możesz jednak zauważyć, że tak naprawdę nie rozwiązuje to całego problemu - klawiatura nie otworzyła się dla mnie, jeśli była wcześniej otwarta przed zmianą orientacji. We wszystkich innych przypadkach zachowanie wydawało się prawidłowe.Następnie musimy wdrożyć jedno z wymienionych tutaj rozwiązań. Najczystszym, jaki znalazłem, był George Maisuradze - użyj boolean callback z hideSoftInputFromWindow:
Zapisałem tę wartość w
onSaveInstanceState
metodzie mojego fragmentu i odzyskałem jąonCreate
. Następnie na siłę pokazałem klawiaturę,onCreateView
jeśli miała wartośćtrue
(zwraca wartość true, jeśli klawiatura jest widoczna przed faktycznym ukryciem jej przed zniszczeniem fragmentu).źródło
Oto moje rozwiązanie i działa. Zamiast szukać rozmiaru w pikselach, po prostu sprawdź, czy wysokość widoku zawartości zmieniła się, czy nie:
źródło
Nie twórz żadnego twardego kodu. Najlepszym sposobem jest zmiana rozmiaru widoków podczas ustawiania ostrości na EditText dzięki KeyBord Show. Możesz to zrobić, dodając właściwość zmiany rozmiaru działania do pliku manifestu, używając poniższego kodu.
android:windowSoftInputMode="adjustResize"
źródło
Istnieje bezpośredni sposób, aby się tego dowiedzieć. I nie wymaga żadnych zmian w układzie.
Działa więc również w trybie pełnego ekranu.
Sztuka polega na tym, że próbujesz ukryć lub pokazać miękką klawiaturę i uchwycić wynik tej próby.
Bez paniki, to tak naprawdę nie pokazuje ani nie ukrywa klawiatury. Po prostu pytamy o państwo.
Aby być na bieżąco, możesz po prostu powtórzyć operację, np. Co 200 milisekund, używając programu obsługi.
Implementacja znajduje się tutaj: https://stackoverflow.com/a/27567074/2525452
źródło
myślę, że ta metoda pomoże ci dowiedzieć się, czy klawiatura jest widoczna czy nie.
źródło
Nowa odpowiedź Reubena Scrattona (oblicz różnicę wysokości
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
) nie będzie działać w aktywności, jeśli ustawisz tryb półprzezroczystego paska stanu.jeśli używasz półprzezroczystego paska stanu,
activityRootView.getHeight()
nigdy nie zmieni pogody, widoczna jest klawiatura programowa. zawsze zwróci wysokość aktywności i pasek stanu.Na przykład Nexus 4, Android 5.0.1, ustawiony
android:windowTranslucentStatus
na true, zwróci 1184 na zawsze, nawet ime mają opend. Jeśli ustawiszandroid:windowTranslucentStatus
false, zwróci poprawnie Wysokość, jeśli będzie niewidoczny, zwróci 1134 (nie obejmuje paska stanu)。 zamknij ime, może zwróci 5xx może (zależy od wysokości ime)Nie wiem, czy to błąd, próbowałem na 4.4.4 i 5.0.1, wynik jest taki sam.
Tak więc, do tej pory, druga najbardziej uzgodniona odpowiedź, rozwiązanie Kachi będzie najbezpieczniejszym sposobem obliczenia wysokości obrazu. Oto kopia:
źródło
Metoda, która nie wymaga LayoutListener
W moim przypadku chciałbym zapisać stan klawiatury przed wymianą mojego fragmentu. I wywołać metodę hideSoftInputFromWindow z
onSaveInstanceState
, która zamyka klawiaturę i powraca mi czy klawiatura była widoczna lub nie.Ta metoda jest prosta, ale może zmienić stan klawiatury.
źródło
Wiem, że to stary post, ale myślę, że jest to najprostsze podejście, jakie znam, a moim urządzeniem testowym jest Nexus 5. Nie próbowałem tego na innych urządzeniach. Mam nadzieję, że inni podzielą się swoim podejściem, jeśli stwierdzą, że mój kod nie jest dobry :)
imm.hideSoftInputFromWindow zwraca wartość logiczną.
Dzięki,
źródło
Powyższej funkcji używam do sprawdzenia, czy klawiatura jest widoczna. Jeśli tak, to go zamykam.
Poniżej pokazano dwie wymagane metody.
Najpierw zdefiniuj wykonalną wysokość okna w programie onCreate.
Następnie dodaj metodę logiczną, która pobiera wysokość okna w tym przypadku. Jeśli nie pasuje do oryginału (zakładając, że nie zmieniasz go po drodze ...), klawiatura jest otwarta.
Frotz!
źródło
Wiem, jak dokładnie można ustalić, czy klawiatura jest ukryta, czy nie.
Działa to na tabletach. Gdy pasek nawigacyjny jest wyświetlany poziomo.
źródło