Dużo badałem, aby dostosować układ, gdy klawiatura programowa jest aktywna i udało mi się ją zaimplementować, ale problem pojawia się, gdy używam android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
tego w moim tagu aktywności w pliku manifestu.
Do tego użyłem android:windowSoftInputMode="adjustPan|adjustResize|stateHidden"
różnych opcji, ale bez powodzenia.
Potem zaimplementowałem FullScreen
programowo i próbowałem różnych układów, FullScreen
ale wszystko na próżno.
Skierowałem te linki i obejrzałem tutaj wiele postów związanych z tym problemem:
http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html
http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/
Oto kod xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/masterContainerView"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff">
<ScrollView android:id="@+id/parentScrollView"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView android:id="@+id/setup_txt" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Setup - Step 1 of 3"
android:textColor="@color/top_header_txt_color" android:textSize="20dp"
android:padding="8dp" android:gravity="center_horizontal" />
<TextView android:id="@+id/txt_header" android:layout_width="fill_parent"
android:layout_height="40dp" android:text="AutoReply:"
android:textColor="@color/top_header_txt_color" android:textSize="14dp"
android:textStyle="bold" android:padding="10dp"
android:layout_below="@+id/setup_txt" />
<EditText android:id="@+id/edit_message"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Some text here." android:textSize="16dp"
android:textColor="@color/setting_editmsg_color" android:padding="10dp"
android:minLines="5" android:maxLines="6" android:layout_below="@+id/txt_header"
android:gravity="top" android:scrollbars="vertical"
android:maxLength="132" />
<ImageView android:id="@+id/image_bottom"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_below="@+id/edit_message" />
</LinearLayout>
</ScrollView>
<RelativeLayout android:id="@+id/scoringContainerView"
android:layout_width="fill_parent" android:layout_height="50px"
android:orientation="vertical" android:layout_alignParentBottom="true"
android:background="#535254">
<Button android:id="@+id/btn_save" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:layout_marginTop="7dp" android:layout_marginRight="15dp"
android:layout_below="@+id/edit_message"
android:text = "Save" />
<Button android:id="@+id/btn_cancel" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginTop="7dp"
android:layout_marginRight="10dp" android:layout_below="@+id/edit_message"
android:layout_toLeftOf="@+id/btn_save" android:text = "Cancel" />
</RelativeLayout>
</RelativeLayout>
Chcę, aby dolne 2 przyciski przesunęły się do góry, gdy pojawi się klawiatura programowa.
źródło
android:windowSoftInputMode="adjustPan"
powiedz mi, czy to działa ..adjustResize
iadjustPan
jednocześnie z javadocandroid.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE
: „To nie może być łączone z {@link SOFT_INPUT_ADJUST_PAN}”Odpowiedzi:
Opierając się na obejściu yghm, stworzyłem wygodną klasę, która pozwala mi rozwiązać problem za pomocą jednowierszowego (oczywiście po dodaniu nowej klasy do kodu źródłowego). Jednowierszowy to:
Klasa implementacji to:
Mam nadzieję, że to komuś pomoże.
źródło
return (r.bottom - r.top);
go,return r.bottom
aby działał na moim HTC One Mini, w przeciwnym razie widok aktywności zostałby przesunięty zbyt wysoko przez rozmiar paska stanu. Nie testowałem tego jeszcze na innym urządzeniu. Mam nadzieję, że to pomoże.frameLayoutParams.height = usableHeightSansKeyboard;
muszę użyć,frameLayoutParams.height = usableHeightNow;
jeśli nie, niektóre elementy wypadają poza ekran.Ponieważ odpowiedź została już wybrana i wiadomo, że problem jest błędem, pomyślałem, że dodam „Możliwe rozwiązanie”.
Możesz przełączać tryb pełnego ekranu, gdy wyświetlana jest klawiatura ekranowa. Dzięki temu funkcja „adjustPan” będzie działać poprawnie.
Innymi słowy, nadal używam @android: style / Theme.Black.NoTitleBar.Fullscreen jako część motywu aplikacji i stateVisible | adjustResize jako część miękkiego trybu wprowadzania w oknie aktywności, ale aby zmusić je do współpracy, muszę przełączyć tryb pełnoekranowy zanim pojawi się klawiatura.
Użyj następującego kodu:
Wyłącz tryb pełnego ekranu
Włącz tryb pełnego ekranu
Uwaga - inspiracja wzięła się z: Ukrywania tytułu w trybie pełnoekranowym
źródło
Wypróbowałem rozwiązanie od Josepha Johnsona , ale tak jak inni natknąłem się na problem luki między treścią a klawiaturą. Ten problem występuje, ponieważ podczas korzystania z trybu pełnoekranowego tryb wprowadzania programowego jest zawsze panoramowany . To panoramowanie koliduje z rozwiązaniem Josepha, gdy aktywujesz pole wejściowe, które byłoby ukryte przez miękkie wejście.
Kiedy pojawia się miękki sygnał wejściowy, zawartość jest najpierw przesuwana w panoramie na podstawie jej oryginalnej wysokości, a następnie zmieniana zgodnie z układem wymaganym przez rozwiązanie Josepha. Zmiana rozmiaru i późniejszy układ nie cofają panoramowania, co powoduje powstanie luki. Pełna kolejność wydarzeń to:
Nie można wyłączyć panoramowania, ale można wymusić przesunięcie panoramy na 0, zmieniając wysokość zawartości. Można to zrobić w odbiorniku, ponieważ jest uruchamiane przed panoramowaniem. Ustawienie wysokości treści na dostępną wysokość zapewnia płynne wrażenia użytkownika, tj. Brak migotania.
Ja też dokonałem tych zmian. Jeśli którykolwiek z tych elementów powoduje problemy, daj mi znać:
getWindowVisibleDisplayFrame
.Rect
Są buforowane, aby zapobiec trochę niepotrzebnych śmieci.Został przetestowany na Nexusie 5 i emulatorach z poziomami API 16-24 z ekranami o rozmiarach od małych do dużych.
Kod został przeniesiony do Kotlin, ale przeniesienie moich zmian z powrotem na Javę jest proste. Daj mi znać jeśli potrzebujesz pomocy:
źródło
possiblyResizeChildOfContent
wywołaniu, jak iremoveListener
wywołaniu, a nawet po osiągnięciuremoveListener
punktu przerwaniapossiblyResizeChildOfContent
nadal jest wywoływana. Czy ktoś jeszcze ma ten problem?Właśnie znalazłem proste i niezawodne rozwiązanie, jeśli korzystasz z podejścia systemowego UI ( https://developer.android.com/training/system-ui/immersive.html ).
Działa w przypadku, gdy używasz
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
np. Gdy używaszCoordinatorLayout
.To nie zadziała
WindowManager.LayoutParams.FLAG_FULLSCREEN
(ten, który możesz również ustawić w motywieandroid:windowFullscreen
), ale możesz osiągnąć podobny efekt zSYSTEM_UI_FLAG_LAYOUT_STABLE
(który „ma ten sam efekt wizualny” zgodnie z dokumentacją ) i to rozwiązanie powinno działać ponownie.Przetestowałem to na moim urządzeniu z systemem Marshmallow.
Kluczowe jest to, że klawiatury programowe są również jednym z okien systemowych (takie jak pasek stanu i pasek nawigacji), więc
WindowInsets
wysyłane przez system zawierają dokładne i wiarygodne informacje na jego temat.W przypadku użycia, na przykład w
DrawerLayout
przypadku, gdy próbujemy rysować za paskiem stanu, możemy utworzyć układ, który ignoruje tylko górną wstawkę i stosuje dolną wstawkę, która odpowiada za klawiaturę programową.Oto mój zwyczaj
FrameLayout
:I aby z niego skorzystać:
Powinno to teoretycznie działać na każdym urządzeniu bez szalonych modyfikacji, znacznie lepiej niż jakikolwiek hack, który próbuje wziąć losowy
1/3
lub1/4
rozmiar ekranu jako odniesienie.(Wymaga API 16+, ale używam pełnego ekranu tylko w Lollipop + do rysowania za paskiem stanu, więc jest to najlepsze rozwiązanie w tym przypadku.)
źródło
Należy pamiętać, że
android:windowSoftInputMode="adjustResize"
nie działa, gdyWindowManager.LayoutParams.FLAG_FULLSCREEN
jest ustawiony na aktywność. Masz dwie możliwości.Wyłącz tryb pełnoekranowy dla swojej aktywności. Aktywność nie jest zmieniana w trybie pełnoekranowym. Możesz to zrobić w xml (zmieniając temat działania) lub w kodzie Java. Dodaj następujące wiersze do metody onCreate ().
LUB
Użyj alternatywnego sposobu, aby przejść do trybu pełnoekranowego. Dodaj następujący kod do metody onCreate ().
Należy pamiętać, że metoda-2 działa tylko w systemie Android 4.1 i nowszych.
źródło
Musiałem też zmierzyć się z tym problemem i miałem pracę, którą sprawdziłem na HTC One, Galaxy S1, S2, S3, Note i HTC sensation.
umieść odbiornik globalnego układu w widoku głównym układu
i tam sprawdziłem różnicę wysokości i jeśli różnica wysokości ekranu jest większa niż jedna trzecia na wysokości ekranu, to możemy założyć, że klawiatura jest otwarta. wziął to z tej odpowiedzi .
to prawdopodobnie nie jest kuloodporne i może na niektórych urządzeniach to nie zadziała, ale zadziałało dla mnie i mam nadzieję, że ci też pomoże.
źródło
Wdrożyłem rozwiązanie Josepha Johnsona i działa dobrze, zauważyłem, że po zastosowaniu tego rozwiązania czasami szuflada aplikacji nie zamyka się poprawnie. Dodałem funkcję usuwania nasłuchiwania removeOnGlobalLayoutListener, gdy użytkownik zamknie fragment, w którym znajdują się edittexts.
używa klasy, w której znajdują się moje edittexts
źródło
Dodaj
android:fitsSystemWindows="true"
do układu, a ten układ zmieni rozmiar.źródło
Aby to działało z FullScreen:
Użyj wtyczki klawiatury jonowej. Pozwala to nasłuchiwać, kiedy klawiatura pojawia się i znika.
OnDeviceReady dodaj następujące detektory zdarzeń:
Logika:
Zasadniczo, jeśli różnica wynosi minus, to jest to liczba pikseli, które pokrywa klawiatura na wejściu. Więc jeśli dostosujesz swój nadrzędny div o to, to powinno temu przeciwdziałać.
Dodanie limitów czasu do logiki mówi, że 300 ms powinno również zoptymalizować wydajność (ponieważ pozwoli to na pojawienie się czasu na klawiaturze.
źródło
Wypróbowałem lekcje Josepha Johnsona i zadziałało, ale nie do końca spełniło moje potrzeby. Zamiast emulować android: windowSoftInputMode = "adjustResize", potrzebowałem emulować android: windowSoftInputMode = "adjustPan".
Używam tego do pełnoekranowego widoku internetowego. Aby przesunąć widok treści do właściwej pozycji, muszę użyć interfejsu javascript, który dostarcza szczegółowych informacji na temat pozycji elementu strony, na którym jest fokus, a zatem otrzymuje dane wejściowe z klawiatury. Pominąłem te szczegóły, ale podałem moje przepisanie klasy Josepha Johnsona. Zapewni to bardzo solidną podstawę do zaimplementowania niestandardowej panoramy w porównaniu do jego zmiany rozmiaru.
źródło
Rzeczywiście wygląd miękkiej klawiatury nie wydaje się wpływać
Activity
w żaden sposób na to, cowindowSoftInputMode
wybiorę wFullScreen
trybie.Chociaż nie mogłem znaleźć zbyt wielu dokumentacji na temat tej właściwości, myślę, że
FullScreen
tryb został zaprojektowany dla aplikacji do gier, które nie wymagają dużego użycia miękkiej klawiatury. Jeśli jest to działanie, które wymaga interakcji użytkownika z klawiaturą programową, rozważ użycie motywu innego niż FullScreen. Możesz wyłączyć pasek tytułu za pomocąNoTitleBar
motywu. Dlaczego chcesz ukryć pasek powiadomień?źródło
Po prostu zachowaj jako
android:windowSoftInputMode="adjustResize"
. Ponieważ jest podawany, aby zachować tylko jedno z"adjustResize"
i"adjustPan"
(Tryb regulacji okna jest określany za pomocą adjustResize lub adjustPan. Zaleca się, aby zawsze określać jedno lub drugie). Możesz go znaleźć tutaj: http://developer.android.com/resources/articles/on-screen-inputs.htmlU mnie działa idealnie.
źródło
Obecnie używam tego podejścia i działa jak urok. Sztuczka polega na tym, że uzyskujemy wysokość klawiatury z różnych metod na 21 powyżej i poniżej, a następnie używamy jej jako dolnego wypełnienia naszego widoku głównego w naszej aktywności. Założyłem, że Twój układ nie wymaga górnej wyściółki (znajduje się poniżej paska stanu), ale jeśli tak, poinformuj mnie, żebym zaktualizował moją odpowiedź.
MainActivity.java
Nie zapomnij zaadresować swojego widoku głównego za pomocą identyfikatora:
activity_main.xml
Mam nadzieję, że to komuś pomoże.
źródło
używaj tylko
android:windowSoftInputMode="adjustResize|stateHidden
podczas używania AdjustPan, a następnie wyłącz właściwość zmiany rozmiaruźródło
źródło
na podstawie https://stackoverflow.com/a/19494006/1815624 i chęci, aby tak się stało ...
zaktualizowany pomysł
łączenie odpowiedzi od
Odpowiedni kod:
Pełne źródło na https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.java
stary pomysł
Utwórz statyczną wartość wysokości kontenera przed otwarciem klawiatury Ustaw wysokość kontenera na podstawie
usableHeightSansKeyboard - heightDifference
czasu otwarcia klawiatury i przywróć zapisaną wartość po jej zamknięciuMetody w MainActivity
Przykład kontenera XML
podobnie marginesy można dodać w razie potrzeby ...
Inną kwestią jest użycie dopełnienia, którego przykład można znaleźć pod adresem:
https://github.com/mikepenz/MaterialDrawer/issues/95#issuecomment-80519589
źródło
1) Utwórz KeyboardHeightHelper:
2) Pozwól swojej aktywności na pełny ekran:
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
3) Posłuchaj zmian wysokości klawiatury i dodaj dolną wyściółkę dla swojego widoku:
Tak więc za każdym razem, gdy na ekranie pojawi się klawiatura - dolne wypełnienie widoku ulegnie zmianie, a treść zostanie ponownie ułożona.
źródło
Chcesz, aby dolny pasek przylegał do dołu widoku, ale kiedy klawiatura jest wyświetlana, powinna przesunąć się w górę, aby umieścić ją nad klawiaturą, prawda?
Możesz wypróbować ten fragment kodu:
BottomBar pozostanie na dole widoku, a LinearLayout zawierający ScrollView zajmie to, co pozostało z widoku po wyświetleniu górnego / dolnego paska i klawiatury. Daj mi znać, jeśli to działa również dla Ciebie.
źródło
Dziękuję Józefie za odpowiedź. Jednak w metodzie prawdopodobnieResizeChildOfContent () część
nie działało dla mnie, ponieważ dolna część widoku została ukryta. Musiałem więc wziąć globalną zmienną restoreHeight iw konstruktorze wstawiłem ostatnią linię
a potem wymieniłem poprzednią wymienioną część na
Ale nie mam pojęcia, dlaczego twój kod nie zadziałał dla mnie. Byłoby bardzo pomocne, gdyby ktoś mógł rzucić na to światło.
źródło
Używałem trybu pełnoekranowego tylko do ukrycia paska stanu. Jednak chcę, aby aplikacja zmieniała rozmiar po wyświetleniu klawiatury. Wszystkie inne rozwiązania (prawdopodobnie ze względu na wiek postu) były skomplikowane lub niemożliwe do mojego użycia (chcę uniknąć zmiany kodu Java dla pakietu PhoneGap Build).
Zamiast używać pełnego ekranu, zmodyfikowałem konfigurację dla Androida, aby nie była pełnoekranowa:
I dodał
cordova-plugin-statusbar
, za pomocą wiersza poleceń:Po załadowaniu aplikacji po prostu wywołuję metodę we wtyczce, aby się ukryć, na przykład:
To działa jak urok. Jedynym prawdziwym minusem jest to, że pasek stanu jest wyraźnie widoczny podczas ładowania aplikacji. Dla moich potrzeb to nie był problem.
źródło
Wypróbowałem wszystkie możliwe odpowiedzi ze stackOverflow, w końcu rozwiązałem po tygodniu Długie wyszukiwanie. Użyłem układu współrzędnych i zmieniłem to za pomocą linearLayout i mój problem został rozwiązany. Nie wiem, czy w układzie współrzędnych są błędy lub coś mojego.
źródło
Próbowałem wielu rozwiązań, w tym Josepha Johnsona i Johana Stuytsa. Ale w rezultacie otrzymałem białą przestrzeń między treścią a klawiaturą na niektórych urządzeniach (takich jak Lenovo s820) we wszystkich przypadkach. Więc wprowadziłem kilka zmian w ich kodach i wreszcie otrzymałem działające rozwiązanie.
Mój pomysł oparty na dodaniu marginesu u góry zawartości, gdy klawiatura jest wyświetlana.
Jak widać, dodaję 30 px do różnicy, ponieważ między górą ekranu a strefą treści z marginesem jest mała biała przestrzeń. I nie wiem, skąd się to pojawia, więc postanowiłem po prostu zmniejszyć marginesy i teraz działa dokładnie tak, jak potrzebowałem.
źródło
Obecnie nie działa problem z dostosowywaniem rozmiaru na pełnym ekranie, który dotyczy zestawu SDK z systemem Android.
Z odpowiedzi, które znalazłem:
rozwiązanie - ale rozwiązanie ma ten problem z obrazem:
Niż znalazłem rozwiązanie i usunąłem jedną niepotrzebną akcję:
Zobacz więc mój kod rozwiązania naprawczego w Kotlin:
Mój kod implementacji naprawy błędów:
źródło
Nie używaj:
ponieważ działa źle. Zamiast tego użyj:
źródło
W moim przypadku ten problem zaczął się pojawiać po dodaniu Crosswalk do mojej aplikacji Cordova. Moja aplikacja nie jest używana na pełnym ekranie i w systemie Android: windowSoftInputMode = "adjustPan".
Miałem już wtyczkę klawiatury jonowej w aplikacji, więc wykrycie, czy klawiatura jest podniesiona czy nie, było dzięki niej łatwe:
Wypróbowałem wszystkie powyższe poprawki, ale prostą linią, która ostatecznie zrobiła to za mnie, była ta część CSS:
Mam nadzieję, że zaoszczędzi ci to kilku dni, które nad tym spędziłem. :)
źródło