Pytanie Zamknij / ukryj miękką klawiaturę systemu Android


mam EditText i a Button w moim układzie.

Po napisaniu w polu edycji i kliknięciu Button, Chcę ukryć wirtualną klawiaturę. Zakładam, że jest to prosty fragment kodu, ale gdzie mogę znaleźć jego przykład?


3093


pochodzenie


Co jeśli masz tylko jeden EditText i kilka przycisków, takich jak pola wyboru i radia? Jedyne miejsce, w którym potrzebna jest klawiatura, znajduje się w jednym EditText. Jak się zarejestrować, aby wiedzieć, że wybrano / kliknięto coś innego, aby ukryć klawiaturę? - AlikElzin-kilaka
czuję się głupio. Nie mogę ukryć klawiatury w ICS. Próbowałem tu wszystkich metod i ich kombinacji. Nie ma mowy. Metoda pokazania tego działa, ale nie mogę ukryć go bez względu na to, jaki token windwelt, ukryć flagi, zamanifestować ustawienia lub świece dla jakichkolwiek świętych. Na pokazie klawiatury zawsze widzę to: I / LatinIME (396): InputType.TYPE_NULL jest określony W / LatinIME (396): Nieoczekiwana klasa wejściowa: inputType = 0x00000000 imeOptions = 0x00000000 - rupps
/ ** * Ta metoda służy do ukrywania miękkiej klawiatury. * @param activity * / public void hideSoftKeyboard (Activity activity) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); } - Harshal Benake
To bardzo smutne, że takie pozornie proste pytanie jest tak popularne. - lang2
Tak, tak, jak Android ma jedno- i dwu-liniowe rozwiązania dla prostych rzeczy. - milosmns


Odpowiedzi:


Aby wyjaśnić to szaleństwo, chciałbym zacząć od przeproszenia w imieniu wszystkich użytkowników Androida za całkowicie niedorzeczną obsługę miękkiej klawiatury Google. Powód jest tak wiele odpowiedzi, każdy inny, na to samo proste pytanie, ponieważ ten API, podobnie jak wiele innych w systemie Android, jest okropnie zaprojektowane. Nie potrafię wymyślić żadnego uprzejmego sposobu na wyrażenie tego.

Chcę ukryć klawiaturę. Spodziewam się dostarczyć Androidowi następujące oświadczenie: Keyboard.hide(). Koniec. Dziękuję Ci bardzo. Ale Android ma problem. Musisz użyć InputMethodManager ukryć klawiaturę. OK, w porządku, to jest interfejs API Androida do klawiatury. ALE! Musisz mieć Context w celu uzyskania dostępu do IMM. Teraz mamy problem. Mogę chcieć ukryć klawiaturę przed klasą statyczną lub użyteczną, która nie ma żadnego zastosowania ani potrzeby Context. lub DUŻO gorzej, IMM wymaga, abyś określił co View (lub co gorsza, co Window) chcesz ukryć klawiaturę od.

To właśnie sprawia, że ​​ukrywanie klawiatury jest tak trudne. Drogi Google: Kiedy szukam przepisu na ciasto, nie ma RecipeProvider na Ziemi, która odmówiłaby podania mi przepisu, chyba że najpierw odpowiedziałbym, że ciasto zostanie zjedzone przez ORAZ gdzie zostanie zjedzone !!

Ta smutna historia kończy się z brzydką prawdą: aby ukryć klawiaturę Android, będziesz musiał podać dwie formy identyfikacji: a Context i albo View lub Window.

Stworzyłem statyczną metodę użytkową, która może wykonać pracę BARDZO solidnie, pod warunkiem, że wywołasz ją z pliku Activity.

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Należy pamiętać, że ta metoda narzędziowa działa WYŁĄCZNIE po wywołaniu z poziomu Activity! Powyższe wywołania metody getCurrentFocus celu Activity aby pobrać właściwy token okna.

Załóżmy jednak, że chcesz ukryć klawiaturę przed EditText hostowane w DialogFragment? Nie możesz użyć powyższej metody:

hideKeyboard(getActivity()); //won't work

To nie zadziała, ponieważ będziesz przekazywać odniesienie do Fragmentgospodarz Activity, który nie będzie miał skoncentrowanej kontroli podczas gdy Fragment jest pokazane! Łał! Tak więc, aby ukryć klawiaturę przed fragmentami, uciekam się do niższego poziomu, bardziej powszechnego i brzydszego:

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Poniżej znajduje się kilka dodatkowych informacji zebranych z więcej straconego czasu na pogoni za tym rozwiązaniem:

Informacje o windowSoftInputMode

Jest jeszcze jeden punkt sporu, o którym należy pamiętać. Domyślnie system Android automatycznie przypisuje początkowe fokus do pierwszego EditText lub sterowanie z możliwością sterowania w twoim Activity. Naturalnie wynika z tego, że InputMethod (zazwyczaj miękka klawiatura) zareaguje na zdarzenie fokusa, pokazując się. The windowSoftInputMode atrybut w AndroidManifest.xml, gdy jest ustawione na stateAlwaysHidden, instruuje klawiaturę, aby zignorowała to automatycznie przypisane początkowe skupienie.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

Prawie niewiarygodnie wydaje się, że nic nie stoi na przeszkodzie, aby klawiatura się otworzyła po dotknięciu kontrolki (chyba że focusable="false" i / lub focusableInTouchMode="false" są przypisane do kontroli). Najwyraźniej ustawienie windowSoftInputMode dotyczy tylko zdarzeń automatycznego ustawiania ostrości, a nie koncentruje się na zdarzeniach wywoływanych przez zdarzenia dotykowe.

W związku z tym, stateAlwaysHidden jest naprawdę źle nazwany. Być może powinno się go nazwać ignoreInitialFocus zamiast.

Mam nadzieję że to pomoże.


AKTUALIZACJA: Więcej sposobów na zdobycie tokena okna

Jeśli nie ma widoku skupionego (np. Może się zdarzyć, jeśli właśnie zmieniłeś fragmenty), istnieją inne widoki, które dostarczą przydatny token okna.

Są to alternatywy dla powyższego kodu if (view == null) view = new View(activity);  Nie odnoszą się one wyraźnie do Twojej aktywności.

Wewnątrz klasy fragmentów:

view = getView().getRootView().getWindowToken();

Biorąc pod uwagę fragment fragment jako parametr:

view = fragment.getView().getRootView().getWindowToken();

Zaczynając od treści treści:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

UPDATE 2: Wyczyść fokus, aby uniknąć ponownego wyświetlania klawiatury, jeśli otworzysz aplikację z tła

Dodaj tę linię na końcu metody:

view.clearFocus();


1024



Nie sądzę, że powinieneś modyfikować softInputMode. Spowoduje to zastąpienie ustawień AndroidManifest. - Kyle Ivey
Wielkie dzięki za dokładną odpowiedź. Wymowne wystarczająco, aby początkujący mógł dobrze zrozumieć miękką klawiaturę. Chciałem ukryć / pokazać klawiaturę z fragmentu i to była najrozsądniejsza odpowiedź, jaką znalazłem. - Tina
Dobra i przydatna odpowiedź. Był to jeden z tych niezwykle rzadkich wpisów na StackOverflow, które z przyjemnością przeczytam. - Rameez Hussain
@AlexanderFarber tak, zazwyczaj an EditText, ale uważam, że wszelkie widoczne View zadziała (np. TextView), ponieważ View służy tylko do wyprowadzenia tokena okna (przedmiotu, z którego ma zostać ukryta klawiatura). Ponadto uważam, że View powinien pochodzić od gospodarza Activity niż Fragment - rmirabelle
@rmirabelle In a Fragment wydaje się, że możesz użyć getActivity().getWindow().getDecorView() - McX


Możesz wymusić na Androidzie ukrywanie wirtualnej klawiatury za pomocą InputMethodManager, dzwonienie hideSoftInputFromWindow, przekazując token okna zawierającego widok skupienia.

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Spowoduje to ukrycie klawiatury we wszystkich sytuacjach. W niektórych przypadkach będziesz chciał przekazać InputMethodManager.HIDE_IMPLICIT_ONLY jako drugi parametr, aby ukryć klawiaturę tylko wtedy, gdy użytkownik jawnie nie wymusił jej pojawienia się (przytrzymując menu).

Uwaga: Jeśli chcesz to zrobić w Kotlin, użyj: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


4176



Dzięki temu wydaje się działać świetnie, jeśli jako drugi parametr zostanie użyte 0. Ale jeśli używam InputMethodManager.HIDE_IMPLICIT_ONLY, klawiatura nigdy nie jest ukryta (chociaż nie trzymam menu). Jakieś wskazówki? - RoflcoptrException
Chłodny. Aby wyjaśnić, to tylko to odrzuca, jeśli istnieje, ale nie będzie zapobiec to się pojawiło, prawda? - Cheezmeister
Pomocne może być wywołanie metody editText.clearFocus () przed ukryciem softInput - user2224350
Powołanie editText.clearFocus() następnie InputMethodManager.HIDE_IMPLICIT_ONLY nawet działa 4.1 - sprocket12
Co pracowało dla mnie na 4.4 / htc zostało wykonane View focused = getCurrentFocus() zdobyć to, co jest Zdecydowanie aktualnie skoncentrowany widok, dzwonienie focused.clearFocus(), i wtedy inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0) (z wyraźnymi flagami). - Ionoclast Brigham


Przydaje się również do ukrywania miękkiej klawiatury:

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

Można tego użyć, aby wyłączyć klawiaturę programowalną, dopóki użytkownik nie dotknie widoku edycji tekstu.


742



Możesz także osiągnąć ten sam efekt, dodając android: windowSoftInputMode = "stateHidden" na swojej aktywności w manifeście. - BoD
Próbowałem tego w Fragmentie (odnosząc się do aktywności właściciela) na poziomie API 9 i niestety nie działało. Próbowałem wywołać go w onResume i onActivityCreated - bez efektu. - AgentKnopf
Pracuję w oknie dialogowym i to zadziałało. Używam Androida 3.2. Umieszczam go w metodzie onCreateDialog (Bundle). To nie działało w metodzie onCreate. Okno dialogowe = super.onCreateDialog (savedInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams. SOFT_INPUT_STATE_ALWAYS_HIDDEN); Powoduje to, że mój widok z EditTexts w nim pojawia się bez klawiatury. Gdy użytkownik dotknie tekstu edycji, pojawi się klawiatura. - flobacca
Nie działa to, gdy fokus jest nadal w EditText (np. Po dotknięciu przycisku). Użyj do tego rozwiązania Reto. - Noumenon
Dlaczego nadpisywanie oczywistych ustawień jest złym pomysłem? Wzywam to z fragmentu. Brak wyraźnego ustawienia, które dotyczy fragmentu ... - Greg Ennis


Mam jeszcze jedno rozwiązanie, aby ukryć klawiaturę:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

Tutaj mijam HIDE_IMPLICIT_ONLY na pozycji showFlag i 0 na pozycji hiddenFlag. Spowoduje to wymuszone zamknięcie miękkiej klawiatury.


294



Używasz flagi ukrywania w parametrze showflags. Działa to tylko dlatego, że stałe używają tych samych liczb całkowitych. Przykład użycia poprawnych flag - Alex
testowane na systemie Android 4.0, podoba mi się to rozwiązanie, ponieważ mam wiele tekstów edycyjnych, przycisków na tej aktywności, które mogą mieć fokus
Dlaczego to pokazuje klawiaturę, jeśli była ukryta? :)
@ Mark: Ponieważ metoda nazywa się "toggleSoftInput", a nie "hideSoftInput" :) - Sver
To rozwiązanie pokazuje klawiaturę, jeśli jest ukryta. To jest niepoprawne - Michael Katkov


Rozwiązanie Meiera działa również dla mnie. W moim przypadku najwyższym poziomem mojej aplikacji jest tabHost i chcę ukryć słowo kluczowe przy przełączaniu kart - otrzymuję token okna z widoku tabHost.

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}

128



Mam to również do pracy z SearchView. Zobacz poniżej moją odpowiedź. Dzięki, mckoss! - Azurespot


Spróbuj tego poniżej kodu w onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

115



Ta metoda działa jako sposób na obejście błędu "nie można ukryć miękkiej klawiatury" w wersjach 2.0 i 2.1, jak opisano w code.google.com/p/android/issues/detail?id=7115 ... Wymieniona wyżej metoda hideSoftInputFromWindow nie działała, gdy próbowałem, ale zrobił to program editView.setInputType (0). - Spike Williams
Jest to zgodne z Javadoc (nie hack), chociaż przepisałbym tę metodę jako editView.setInputType(InputType.TYPE_NULL); - Bostone
działa to jednak, że ukrywa Androida: podpowiedź. Używam Androida 1.5 - Tirtha
@Bostone To nie działa dla SearchView - nmxprime
to jest świetne, gdy trzeba zamknąć klawiaturę z okna dialogowego, nie trzeba pobierać instancji ani niczego i można ją przypisać do wszystkich tekstów edycji, gdy użytkownik naciśnie przycisk zamykający okno dialogowe - I'm_With_Stupid


Aktualizacja: Nie wiem, dlaczego to rozwiązanie już nie działa (właśnie testowałem na systemie Android 23). Proszę użyć rozwiązania Saurabh Pareek zamiast. Oto ona:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

Stara odpowiedź:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

108



Gdzie powinienem umieścić ten kod? Próbowałem wkleić getWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); w onCreate (), ale klawiatura nigdy nie jest ukryta - user2236096
nie działa, testowany w radioGroup.setOnCheckedChangeListener, API 23 - Christian Schäfer
Jeśli przyjrzymy się bliżej, InputMethodManager.HIDE_IMPLICIT_ONLY i InputMethodManager.SHOW_IMPLICIT mają tę samą wartość, która wynosi "1", więc nie ma różnicy między tymi połączeniami. => nie działa - Palejandro
jeśli wywołuje imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); wtedy na ekranie wyświetli się klawiatura :) Najlepsza implementacja to: github.com/ravindu1024/android-keyboardlistener Wstyd w systemie Android SDK - Duna
I don't know why this solution is not work any more - ponieważ to jest Androidwszystko będzie w stanie się zmienić, być może częściowo z powodu złego projektu ... Piszemy niedbale, a potem wszystko wymyślamy i przepisujemy wszystko. - King King


protected void hideSoftKeyboard(EditText input) {
    input.setInputType(0);
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}

63



To działało dla mnie! Ale dlaczego to zrobiłeś input.setInputType (0) ? Nie mogłem współpracować z EditTextView kiedy miałem tę linię kodu (działało, kiedy ją usunąłem). - ymerdrengene
@ymerdrengene Masz rację, musiałem też to usunąć. - Lazy


Jeśli wszystkie pozostałe odpowiedzi tutaj nie działają, tak jak chcesz, istnieje inny sposób ręcznego sterowania klawiaturą.

Utwórz funkcję, która będzie zarządzać niektórymi EditTextWłaściwości:

public void setEditTextFocus(boolean isFocused) {
    searchEditText.setCursorVisible(isFocused);
    searchEditText.setFocusable(isFocused);
    searchEditText.setFocusableInTouchMode(isFocused);

    if (isFocused) {
        searchEditText.requestFocus();
    }
}

Następnie upewnij się, że onFocus of the EditText otwieranie / zamykanie klawiatury:

searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == searchEditText) {
            if (hasFocus) {
                // Open keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
            } else {
                // Close keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
            }
        }
    }
});

Teraz, gdy chcesz ręcznie otworzyć klawiaturę, zadzwoń:

setEditTextFocus(true);

A dla zamknięcia połączenia:

setEditTextFocus(false);

58



+1 - Jeśli chcesz rozpocząć działanie z zamkniętą klawiaturą, użyj tego rozwiązania i dodaj onclicklistener, który ustawia setEditTextFocus (true). Działa jak charme! - schlingel
Mam "Nie mogę rozwiązać kontekstu symbolu", na siódmej i dziesiątej linii drugiego bloku kodu. - gimmegimme
Zamiast tego użyj getContext () - Rotemmiz


Saurabh Pareek ma jak dotąd najlepszą odpowiedź.

Równie dobrze może użyć poprawnych flag.

/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

Przykład rzeczywistego użycia

/* click button */
public void onClick(View view) {      
  /* hide keyboard */
  ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
      .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

  /* start loader to check parameters ... */
}

/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
    /* parameters not valid ... */

    /* show keyboard */
    ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
        .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

    /* parameters valid ... */
}

51



W wersji 2.1 klawiatura wyskakuje, a następnie chowa się. Niedobrze. - halxinate
Jest to najbardziej wydajne rozwiązanie dla najnowszej wersji. Zawsze trzeba będzie go dostosować do starszych wersji. Zwłaszcza przed v3. - Alex
Nie można rozwiązać metody getSystemService () z fragmentami! - Mazen Kasser
@Mazen: użyj fragment.getActivity().getSystemService(); - Johan S
Nie. Na mojej karcie Samsunga, Android 5.0, tak zwany kod "ukryj klawiaturę" powyżej spowoduje PRZEKROCZENIE miękkiej klawiatury - jeśli jest już ukryta, pokaże ją. Jest powód, dla którego funkcja ta ma w nazwie funkcję ROZKŁAD. - ToolmakerSteve