Chiudi / nascondi tastiera virtuale android


3819

Ho un EditTexte un Buttonnel mio layout.

Dopo aver scritto nel campo di modifica e aver fatto clic su Button, voglio nascondere la tastiera virtuale. Presumo che questo sia un semplice pezzo di codice, ma dove posso trovarne un esempio?

Quando si tocca fuori dalla tastiera.


13
Che cosa succede se hai un solo EditText e diversi pulsanti, come caselle di controllo e radio? L'unico posto in cui hai bisogno della tastiera è nel singolo EditText. Come ti registri per sapere che qualcos'altro è stato scelto / cliccato per nascondere la tastiera?
AlikElzin-kilaka,

14
Mi sento stupido. Non riesco a nascondere la tastiera su ICS. Ho provato tutti i metodi qui e le loro combinazioni. Non c'è modo. Il metodo per mostrarlo funziona, ma non posso nasconderlo, non importa quale gettone del vento, nascondere bandiere, manifestare impostazioni o candele a tutti i santi. Su tastiera mostra sempre questo: I / LatinIME (396): InputType.TYPE_NULL è specificato W / LatinIME (396): Classe di input imprevista: inputType = 0x00000000 imeOptions = 0x00000000
rupps

4
/ ** * Questo metodo viene utilizzato per nascondere la tastiera virtuale. * @param activity * / public void hideSoftKeyboard (Activity Activity) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); }
Harshal Benake,

questo ha funzionato per me
nmxprime,

Con i dispositivi che aumentano le dimensioni e la risoluzione dello schermo, nascondere la tastiera virtuale sta diventando meno importante.
Al-Kathiri Khalid,

Risposte:


2038

Per aiutare a chiarire questa follia, vorrei iniziare chiedendo scusa a nome di tutti gli utenti Android per il trattamento assolutamente ridicolo di Google sulla tastiera soft. Il motivo per cui ci sono così tante risposte, ognuna diversa, per la stessa semplice domanda è perché questa API, come molte altre in Android, è progettata in modo orribile. Non riesco a pensare a un modo educato per dirlo.

Voglio nascondere la tastiera. Mi aspetto di fornire Android con la seguente dichiarazione: Keyboard.hide(). La fine. Grazie mille. Ma Android ha un problema. È necessario utilizzare il InputMethodManagerper nascondere la tastiera. OK, bene, questa è l'API di Android per la tastiera. MA! ContextPer poter accedere all'IMM è necessario disporre di un simbolo. Ora abbiamo un problema. Potrei voler nascondere la tastiera da una classe statica o di utilità che non ha alcuna utilità o necessità Context. o E peggio ancora, l'IMM richiede di specificare da che cosa View(o anche peggio, cosa Window) si desidera nascondere la tastiera.

Questo è ciò che rende così difficile nascondere la tastiera. Caro Google: quando cerco la ricetta di una torta, non c'è RecipeProvidersulla Terra che si rifiuterebbe di fornirmi la ricetta a meno che io non risponda per la prima volta CHI sarà mangiata e dove verrà mangiata !!

Questa triste storia termina con la brutta verità: per nascondere la tastiera Android, ti verrà richiesto di fornire 2 forme di identificazione: Contextae Viewo a o a Window.

Ho creato un metodo di utilità statica che può fare il lavoro MOLTO in modo solido, a condizione che tu lo chiami da un 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);
}

Tenere presente che questo metodo di utilità funziona SOLO quando viene chiamato da un Activity! Il metodo sopra chiama getCurrentFocusla destinazione Activityper recuperare il token della finestra corretto.

Ma supponiamo che tu voglia nascondere la tastiera da un EditTextospitato in un DialogFragment? Non puoi usare il metodo sopra per quello:

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

Questo non funzionerà perché passerai un riferimento Fragmentall'host dell'host Activity, che non avrà alcun controllo focalizzato mentre Fragmentviene mostrato! Wow! Quindi, per nascondere la tastiera dai frammenti, ricorro al livello inferiore, più comune e più brutto:

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

Di seguito sono riportate alcune informazioni aggiuntive raccolte da più tempo sprecato nella ricerca di questa soluzione:

Informazioni su windowSoftInputMode

C'è ancora un altro punto di contesa di cui essere consapevoli. Per impostazione predefinita, Android assegnerà automaticamente il focus iniziale al primo EditTexto focus focus nel tuo Activity. Ne consegue naturalmente che InputMethod (in genere la tastiera virtuale) risponderà all'evento focus mostrandosi. L' windowSoftInputModeattributo in AndroidManifest.xml, quando impostato su stateAlwaysHidden, indica alla tastiera di ignorare questo focus iniziale assegnato automaticamente.

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

Quasi incredibile, sembra non fare nulla per impedire l'apertura della tastiera quando si tocca il controllo (a meno che focusable="false"e / o non focusableInTouchMode="false"siano assegnati al controllo). Apparentemente, l'impostazione windowSoftInputMode si applica solo agli eventi di focus automatici, non agli eventi di focus attivati ​​da eventi touch.

Pertanto, stateAlwaysHiddenè MOLTO mal chiamato davvero. Dovrebbe forse essere chiamato ignoreInitialFocusinvece.

Spero che sia di aiuto.


AGGIORNAMENTO: altri modi per ottenere un token finestra

Se non esiste una vista focalizzata (ad es. Può succedere se hai appena cambiato frammenti), ci sono altre viste che forniranno un utile token finestra.

Queste sono alternative al codice sopra if (view == null) view = new View(activity); Non si riferiscono esplicitamente alla tua attività.

All'interno di una classe di frammenti:

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

Dato un frammento fragmentcome parametro:

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

A partire dal tuo corpo di contenuti:

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

AGGIORNAMENTO 2: deselezionare lo stato attivo per evitare di mostrare di nuovo la tastiera se si apre l'app dallo sfondo

Aggiungi questa riga alla fine del metodo:

view.clearFocus();


2
Scrittura molto bella. Una cosa tuttavia, se si avvia un'altra attività al di sopra di essa, che attiva la tastiera, la tastiera sarà comunque presente al ritorno. Risolto il problema rimuovendo la tastiera usando il metodo quando si chiude l'attività principale.
Oyvind

3
@rmirabelle In a Fragmentsembra che tu possa usaregetActivity().getWindow().getDecorView()
McX l'

1
Questo post è fantastico ma ti mancano due parti molto importanti. Le sottili modifiche apportate per versione e per fabbricazione. Ad esempio su una Samsung Galaxy S6 dobbiamo usare .clearFocus () prima di nascondere la tastiera ... in caso contrario la tastiera verrà comunque visualizzata al secondo clic di edittext: S
Warpzit

17
Google dovrebbe proprio fornire tale Keyboard.hide();utilità
HendraWD,

1
[someView] .getContext () << Può essere un caso per attività. È sempre lo stesso oggetto. (Tranne i servizi interni ...)
Oliver Dixon,

4419

Puoi forzare Android a nascondere la tastiera virtuale utilizzando InputMethodManager , chiamando hideSoftInputFromWindow, passando il token della finestra contenente la vista focalizzata.

// 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);
}

Ciò costringerà la tastiera a essere nascosta in tutte le situazioni. In alcuni casi vorrai passare InputMethodManager.HIDE_IMPLICIT_ONLYcome secondo parametro per assicurarti di nascondere la tastiera solo quando l'utente non l'ha forzata esplicitamente a comparire (tenendo premuto il menu).

Nota: se vuoi farlo in Kotlin, usa: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

Sintassi di Kotlin

// Check if no view has focus:
 val view = this.currentFocus
 view?.let { v ->
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager 
  imm?.hideSoftInputFromWindow(v.windowToken, 0)
 }

14
Grazie, sembra funzionare alla grande se si utilizza 0 come secondo parametro. Ma se uso InputMethodManager.HIDE_IMPLICIT_ONLY la tastiera non sarà mai nascosta (anche se non tengo premuto il menu). Qualche suggerimento?
RoflcoptrException,

27
Freddo. Giusto per chiarire, questo lo respinge solo se presente, ma non gli impedirà di spuntare, giusto?
Cheezmeister,

15
Potrebbe essere utile chiamare editText.clearFocus () prima di nascondere softInput
user2224350

111
Chiamare editText.clearFocus()quindi InputMethodManager.HIDE_IMPLICIT_ONLYfunziona anche su4.1
sprocket12

11
Ciò che ha funzionato per me su 4.4 / htc è stato l'esecuzione View focused = getCurrentFocus()per ottenere quella che è sicuramente la vista attualmente focalizzata, chiamando focused.clearFocus()e quindi inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)(con flag chiari).
Ionoclast Brigham,

806

Utile anche per nascondere la tastiera virtuale è:

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

Può essere utilizzato per sopprimere la tastiera virtuale fino a quando l'utente non tocca effettivamente la vista Modifica testo.


116
Puoi anche ottenere lo stesso effetto aggiungendo android: windowSoftInputMode = "stateHidden" sulla tua attività nel manifest.
CdA

7
Ho provato questo in un frammento (riferendosi all'attività proprietaria) su API Level 9 e purtroppo non ha funzionato. Ho provato a chiamarlo in onResume e onActivityCreated - nessun effetto.
AgentKnopf

2
Sto lavorando in una finestra di dialogo e questo ha funzionato. Sto usando Android 3.2. L'ho inserito nel metodo onCreateDialog (Bundle). Non ha funzionato nel metodo onCreate. Dialog dialog = super.onCreateDialog (savedInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams. SOFT_INPUT_STATE_ALWAYS_HIDDEN); Il risultato è che la mia vista con EditTexts appare senza la tastiera. Quando l'utente tocca un testo di modifica, viene visualizzata la tastiera.
flobacca,

4
Questo non funziona quando il focus è ancora in un EditText (come, dopo aver toccato un pulsante). Usa la soluzione di Reto per questo.
Noumenon,

4
Perché l'override delle impostazioni manifest è una cattiva idea? Lo chiamo da un frammento. Non esiste alcuna impostazione manifest applicabile a un frammento ...
Greg Ennis,

349

Ho un'altra soluzione per nascondere la tastiera:

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

Qui passa HIDE_IMPLICIT_ONLYnella posizione di showFlage 0nella posizione di hiddenFlag. Chiuderà forzatamente la tastiera software.


4
Stai usando un flag hide nel parametro showflags. Funziona solo perché le costanti usano gli stessi numeri interi. Esempio usando le bandiere corrette
Alex

testato su Android 4.0, mi piace questa soluzione, perché ho più testi di modifica, pulsanti su quell'attività, che possono avere lo stato

32
@Mark: Perché il metodo si chiama "toggleSoftInput", non "hideSoftInput" :)
Risparmia il

19
Questa soluzione mostra la tastiera se è nascosta. Non è corretto
Michael Katkov,

1
@AkashAggarwal - "Funziona" se ignori il fatto che ha funzionato solo per te perché la tastiera stava mostrando. (INSIEME alla visibilità della tastiera: si nasconde quando viene mostrato, MA lo mostra quando è nascosto !!) PUOI GARANTIRE che in tutte le circostanze, su tutti i dispositivi, per tutte le versioni future di Android, la tastiera NON sarà mostrando al momento in cui lo chiami? Se è così, vai avanti e usalo!
ToolmakerSteve

149

La soluzione di Meier funziona anche per me. Nel mio caso il livello più alto della mia app è un tabHost e voglio nascondere la parola chiave quando si cambia scheda - ottengo il token della finestra dalla vista tabHost.

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

Ho capito che funziona anche con SearchView. Vedi sotto per la mia risposta. Grazie mckoss!
Azurespot,

139

Prova questo codice qui sotto in onCreate()

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

2
Questo metodo funziona come mezzo per aggirare il bug "impossibile nascondere la tastiera" in 2.0 e 2.1 come descritto in code.google.com/p/android/issues/detail?id=7115 ... il metodo hideSoftInputFromWindow elencato sopra non ha funzionato quando l'ho provato, ma editView.setInputType (0) ha fatto.
Spike Williams,

18
Questo è legittimo per Javadoc (non un hack) anche se riscriverei il metodo comeeditView.setInputType(InputType.TYPE_NULL);
Bostone,

3
funziona, tuttavia, nasconde l'androide: suggerimento. sto usando Android 1.5
Tirtha

questo è ottimo per quando è necessario chiudere la tastiera da una finestra di dialogo, non è necessario ottenere un'istanza o altro e può assegnarla a tutti i testi di modifica quando l'utente preme un pulsante che chiude la finestra di dialogo
I'm_With_Stupid

Funziona, ma nasconde anche il cursore. Ho bisogno del cursore, ma nessuna tastiera di sistema.
Stefan Brendle,

129

Aggiornamento: non so perché questa soluzione non funziona più (ho appena testato su Android 23). Si prega di usare la soluzione di Saurabh Pareek invece. Ecco qui:

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

Vecchia risposta:

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

8
Dove devo inserire questo codice? Ho provato a incollare getWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); in onCreate () ma la tastiera non è mai nascosta
user2236096

non funziona, testato in radioGroup.setOnCheckedChangeListener, API 23
Christian Schäfer

Se guardi più da vicino, InputMethodManager.HIDE_IMPLICIT_ONLY e InputMethodManager.SHOW_IMPLICIT hanno lo stesso valore, che è "1", quindi non c'è differenza tra queste chiamate. => non funzionante
Palejandro,

se si chiama imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); la tastiera verrà visualizzata sullo schermo :) La migliore implementazione è: github.com/ravindu1024/android-keyboardlistener Vergogna su Android SDK
Duna,

I don't know why this solution is not work any more- perché è Android , tutto sarà in grado di cambiare, forse in parte di cattivo design ... Scriviamo con noncuranza, quindi cancelliamo tutto e riscriviamo tutto.
King King,

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

5
Questo ha funzionato per me! Ma perché hai inserito input.setInputType (0) ? Non potevo interagire con EditTextView quando avevo quella riga di codice (funzionava quando l'ho rimosso).
Ymerdrengene,

Probabilmente input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE).
CoolMind

Ho rimosso input.setInputType(0);da questo codice. Ha cambiato il comportamento della tastiera e inputTypeper EditText.
CoolMind,

74

Se tutte le altre risposte qui non funzionano come desideri, esiste un altro modo di controllare manualmente la tastiera.

Crea una funzione che gestirà alcune delle EditTextproprietà di:

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

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

Quindi, assicurati che onFocus EditTextapri / chiudi la tastiera:

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);
            }
        }
    }
});

Ora, ogni volta che vuoi aprire manualmente la tastiera chiama:

setEditTextFocus(true);

E per la chiamata di chiusura:

setEditTextFocus(false);

+1: se si desidera iniziare un'attività con la tastiera chiusa, utilizzare questa soluzione e aggiungere un listener onclick che imposta setEditTextFocus (true). Funziona come un incanto!
schlingel,

Ho ottenuto "Impossibile risolvere il contesto del simbolo", sulla settima e decima riga del secondo blocco di codice.
gimmegimme,

Usa invece getContext ()
Rotemmiz il

61

Saurabh Pareek ha la risposta migliore finora.

Potrebbe anche usare le bandiere corrette, però.

/* 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);

Esempio di reale utilizzo

/* 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 ... */
}

1
Questo è il più efficiente per l'ultima versione. Sarà sempre necessario modificarlo per le versioni precedenti. Soprattutto prima della v3.
Alex

2
@Mazen: usofragment.getActivity().getSystemService();
Johan S

Questa è la risposta più completa, che copre sia mostra che nascondi.
André Staltz,

4
No. Sul mio Samsung Tab, Android 5.0, il cosiddetto codice "nascondi tastiera" sopra cambierà la tastiera virtuale - se è già nascosta, lo mostrerà. C'è una ragione per cui questa funzione ha TOGGLE nel nome.
ToolmakerSteve

57

da così ricerca, qui ho trovato una risposta che funziona per me

// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

L'unico che ha funzionato per me per un Motorola con Android 5.1
GMX

55

La breve risposta

Nel tuo OnClickascoltatore chiama onEditorActionil EditTextconIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

Il drill-down

Ritengo che questo metodo sia migliore, più semplice e più allineato con il modello di progettazione di Android. Nel semplice esempio sopra (e di solito nella maggior parte dei casi comuni) avrai uno EditTextche ha / aveva focus e di solito era anche quello che invocava la tastiera in primo luogo (è sicuramente in grado di invocarlo in molti scenari comuni). Nello stesso modo, esso dovrebbe essere quello di liberare la tastiera, di solito che può essere fatto da un ImeAction. Basta vedere come si comporta un EditTextcon android:imeOptions="actionDone", si desidera ottenere lo stesso comportamento con gli stessi mezzi.


Controlla questa risposta correlata


Questa è la risposta. Solo metodo che funziona in versione incrociata. Sono tornato a questa domanda per pubblicare questa risposta perché non pensavo che nessun altro lo sapesse
Noah Passalacqua,

Questa dovrebbe essere la risposta corretta. Invece di indurre Android a nascondere la tastiera quando dovrebbe davvero essere lì, diciamo che l'utente ha finito, il che a sua volta attiva lo stesso ImeAction [nome stupido, lo ammetto] come se l'utente avesse fatto clic su "FATTO" sulla tastiera . In questo modo non fa alcuna differenza se l'utente conferma l'immissione sulla tastiera o tocca il pulsante dell'interfaccia utente.
Oliver Hausler

46

Questo dovrebbe funzionare:

public class KeyBoard {

    public static void show(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
    }

    public static void hide(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
    }

    public static void toggle(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm.isActive()){
            hide(activity); 
        } else {
            show(activity); 
        }
    }
}

KeyBoard.toggle(activity);

Ha funzionato in parte, anche se la tastiera era nascosta "isActive ()" restituisce false!
xpto

Ovviamente lo fa, dovrebbe. O forse non ti capisco. Ad ogni modo, potresti integrare la classe hide()e i show()metodi per avere un maggiore controllo su quando dovrebbe essere mostrato e quando no. Funziona anche per me, l'ho fatto anch'io :)
Modificherò l'

@YoushaAleayoub sì, lo sarà. KeyBoard.toggle(fragment.getActivity())
slinden77,

@ slinden77, lol, sto parlando della tua risposta ... non di questa che hai commentato. Quindi quella risposta NON funzionerà ancora.
Yousha Aleayoub,

@YoushaAleayoub uhm sì lo farà. La domanda originale non menziona i frammenti, tu sei colui che ha menzionato i frammenti. Quindi la mia risposta è perfettamente valida. Per usarlo con i frammenti, chiama il metodo in modo diverso da a Fragment, come un commentato. Scopri come utilizzare i metodi, per favore e poi torna indietro. Stai confondendo le persone con le tue sciocche risposte
slinden77,

43

Sto usando una tastiera personalizzata per inserire un numero esadecimale, quindi non posso mostrare la tastiera IMM ...

In v3.2.4_r1 è setSoftInputShownOnFocus(boolean show)stato aggiunto per controllare il tempo o per non visualizzare la tastiera quando un TextView viene messo a fuoco, ma è ancora nascosto, quindi è necessario utilizzare il riflesso:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

Per le versioni precedenti, ho ottenuto risultati molto buoni (ma tutt'altro che perfetto) con a OnGlobalLayoutListener, aggiunto con l'aiuto di a ViewTreeObserverdalla mia vista di root e quindi controllando se la tastiera è mostrata in questo modo:

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

Quest'ultima soluzione potrebbe mostrare la tastiera per una frazione di secondo e fare casini con gli handle di selezione.

Quando nella tastiera si entra a schermo intero, onGlobalLayout non viene chiamato. Per evitarlo, usa TextView # setImeOptions (int) o nella dichiarazione XML di TextView:

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

Aggiornamento: ho appena trovato quali finestre di dialogo non mostrano mai la tastiera e funzionano in tutte le versioni:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

Grazie. Le due bandiere FLAG_ALT_FOCUSABLE_IM e FLAG_ALT_FOCUSABLE_IM sono in realtà l'unica cosa che mi ha aiutato nel mio caso. Non volevo che una tastiera fosse mostrata nella mia attività, nemmeno quando l'utente faceva clic su un edittext. (Ho creato la mia "tastiera").
Daniel Novak,

Soluzione interessante, tuttavia, se l'attività frontale non è a schermo intero, la tastiera è visibile dietro di essa. Inoltre è ancora visibile l'ausilio al movimento del cursore della tastiera. E non è personalizzabile.
Halxinate,

Sono d'accordo con questo. Di tutti i modi possibili funziona solo il metodo getWindow (). SetFlags (), almeno su Android 5.1 di serie. Si noti che setSoftInputShownOnFocus () è ora setShowSoftInputOnFocus () e non è più nascosto ma non funziona, almeno non quando l'utente tocca il campo.
Olefevre,

Il tuo "aggiornamento" è stata l'unica soluzione funzionante per me. Sto cercando una soluzione almeno due ore :)
Stefan Brendle

33
public void setKeyboardVisibility(boolean show) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(show){
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }else{
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    }
}

30

Ho trascorso più di due giorni a lavorare su tutte le soluzioni pubblicate nel thread e le ho trovate carenti in un modo o nell'altro. Il mio esatto requisito è di avere un pulsante che con affidabilità al 100% mostrerà o nasconderà la tastiera su schermo. Quando la tastiera si trova nel suo stato nascosto non dovrebbe riapparire, indipendentemente dai campi di input su cui l'utente fa clic. Quando è nel suo stato visibile, la tastiera non dovrebbe scomparire, indipendentemente dai pulsanti su cui l'utente fa clic. Questo deve funzionare su Android 2.2+ fino ai dispositivi più recenti.

Puoi vedere un'implementazione funzionante di questo nel mio RPN pulito app .

Dopo aver testato molte delle risposte suggerite su un numero di telefoni diversi (inclusi froyo e dispositivi di pan di zenzero) è diventato evidente che le app Android possono essere affidabili:

  1. Nasconde temporaneamente la tastiera. Riapparirà di nuovo quando un utente mette a fuoco un nuovo campo di testo.
  2. Mostra la tastiera all'avvio di un'attività e imposta un flag sull'attività che indica che la tastiera dovrebbe essere sempre visibile. Questo flag può essere impostato solo quando si sta inizializzando un'attività.
  3. Segna un'attività per non mostrare o consentire mai l'uso della tastiera. Questo flag può essere impostato solo quando si sta inizializzando un'attività.

Per me, nascondere temporaneamente la tastiera non è abbastanza. Su alcuni dispositivi riapparirà non appena viene focalizzato un nuovo campo di testo. Poiché la mia app utilizza più campi di testo su una pagina, la messa a fuoco di un nuovo campo di testo comporterà nuovamente il backup della tastiera nascosta.

Sfortunatamente le voci 2 e 3 nell'elenco funzionano solo quando si avvia un'attività. Una volta che l'attività è diventata visibile, non è possibile nascondere o mostrare permanentemente la tastiera. Il trucco è riavviare effettivamente l'attività quando l'utente preme il pulsante di attivazione / disattivazione della tastiera. Nella mia app quando l'utente preme il pulsante di attivazione / disattivazione della tastiera, viene eseguito il codice seguente:

private void toggleKeyboard(){

    if(keypadPager.getVisibility() == View.VISIBLE){
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, true);
        i.putExtras(state);

        startActivity(i);
    }
    else{
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, false);
        i.putExtras(state);

        startActivity(i);
    }
}

Questo fa sì che l'attività corrente venga salvata in un pacchetto e quindi l'attività viene avviata, passando attraverso un valore booleano che indica se la tastiera deve essere mostrata o nascosta.

All'interno del metodo onCreate viene eseguito il seguente codice:

if(bundle.getBoolean(SHOW_KEYBOARD)){
    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
    getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
            WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

Se deve essere visualizzata la tastiera virtuale, viene indicato a InputMethodManager di mostrare la tastiera e alla finestra viene indicato di rendere sempre visibile l'input software. Se la tastiera software deve essere nascosta, viene impostato WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM.

Questo approccio funziona in modo affidabile su tutti i dispositivi su cui ho provato - da un telefono HTC di 4 anni con Android 2.2 fino a un Nexus 7 con 4.2.2. L'unico svantaggio di questo approccio è che devi stare attento con la gestione del pulsante Indietro. Poiché la mia app ha essenzialmente una sola schermata (è una calcolatrice), posso ignorare onBackPressed () e tornare alla schermata principale dei dispositivi.


1
soluzione alternativa elaborata, ma penso che sia troppo per ricreare migliaia di oggetti solo per nascondere la tastiera. Non so chi abbia progettato l'IMM per Android, ma puzza come un APi di Windows. Secondo me, un buon IME dovrebbe avere due metodi: nascondere e mostrare :-)
rupps

È tutto vero, ma la mia soluzione ha un vantaggio: funziona sempre! Non c'è altra soluzione che potrei trovare per attivare o disattivare la tastiera, indipendentemente da quali campi dell'interfaccia utente hanno lo stato attivo, ciò che l'utente ha fatto per attivare e disattivare la tastiera e la versione di Android che stanno eseguendo: - \
Luke Sleeman

Amico, sono assolutamente alla disperata ricerca di nascondere la tastiera. Ho provato migliaia di cose e nessuno funziona. Ma la tua soluzione è troppo per me, dovrei ricreare come 10 frammenti, inizializzare i servizi, eliminare un sacco di riferimenti deboli .... sai? il GC sarebbe semplicemente buttato via come 25mb: S ... Sto ancora cercando un modo affidabile per farlo :(
rupps

@Dmitry bene non è un mondo ciao ... è un'applicazione complessa per tablet. Mi rifiuto di scaricarlo completamente dalla memoria solo per nascondere una tastiera sciocca ... Comunque ho trovato qualcosa che funziona combinando le mille soluzioni proposte qui :)
rupps

27

In alternativa a questa soluzione completa , se si desidera chiudere la tastiera virtuale da qualsiasi luogo senza avere un riferimento al campo (EditText) utilizzato per aprire la tastiera, ma si desidera comunque farlo se il campo era attivo, è possibile utilizzare questo (da un'attività):

if (getCurrentFocus() != null) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

25

Grazie a questa risposta SO , ho ricavato quanto segue che, nel mio caso, funziona bene durante lo scorrimento dei frammenti di un ViewPager ...

private void hideKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

private void showKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

21

Le risposte sopra funzionano per diversi scenari ma se vuoi nascondere la tastiera all'interno di una vista e lottare per ottenere il giusto contesto, prova questo:

setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        hideSoftKeyBoardOnTabClicked(v);
    }
}

private void hideSoftKeyBoardOnTabClicked(View v) {
    if (v != null && context != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

e per ottenere il contesto recuperalo dal costruttore :)

public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init();
}

18

Se si desidera chiudere la tastiera virtuale durante un'unità o un test funzionale, è possibile farlo facendo clic sul "pulsante Indietro" dal test:

// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

Ho messo il "pulsante indietro" tra virgolette, poiché quanto sopra non attiva onBackPressed()l'attività in questione. Chiude solo la tastiera.

Assicurati di mettere in pausa un po 'di tempo prima di andare avanti, poiché ci vuole un po' di tempo per chiudere il pulsante Indietro, quindi i clic successivi su Viste, ecc., Non verranno registrati fino a dopo una breve pausa (1 secondo è abbastanza lungo ).


16

Ecco come lo fai in Mono per Android (AKA MonoDroid)

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

1
Cosa c'è searchboxnello snippet?
PCoder,

16

Questo ha funzionato per me per tutto il bizzarro comportamento della tastiera

private boolean isKeyboardVisible() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    mRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
    return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}

protected void showKeyboard() {
    if (isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (getCurrentFocus() == null) {
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    } else {
        View view = getCurrentFocus();
        inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
    }
}

protected void hideKeyboard() {
    if (!isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View view = getCurrentFocus();
    if (view == null) {
        if (inputMethodManager.isAcceptingText())
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
    } else {
        if (view instanceof EditText)
            ((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
        inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

1
Penso di aver provato 10 risposte prima di questo. Aveva rinunciato alla speranza. Grazie uomo.
Bolling

Che cos'è mRootView?
justdan0227,

14

Aggiungi alla tua attività android:windowSoftInputMode="stateHidden"nel file manifest. Esempio:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>

14

Metodo semplice e facile da usare, basta chiamare hideKeyboardFrom (YourActivity.this); per nascondere la tastiera

/**
 * This method is used to hide keyboard
 * @param activity
 */
public static void hideKeyboardFrom(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

13

Usa questo codice ottimizzato nella tua attività:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

Funziona bene. Grazie
Alif,

12
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

dopo quella chiamata su onTouchListener:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

Prova anche questo - ha funzionato per me: InputMethodManager imm = ((InputMethodManager) getSystemService (Activity.INPUT_METHOD_SERVICE)); imm.hideSoftInputFromWindow (getWindow (). getCurrentFocus (). getWindowToken (), 0);
zmicer,

12

Usa questo

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

12

Nel mio caso, stavo usando un SearchView nella barra delle azioni. Dopo che un utente esegue una ricerca, la tastiera si aprirà di nuovo.

L'uso di InputMethodManager non ha chiuso la tastiera. Ho dovuto cancellare Focus e impostare il focusable della vista di ricerca su false:

mSearchView.clearFocus();
mSearchView.setFocusable(false);

1
Molto intelligente. Se l'utente desidera un'altra ricerca, fai di nuovo clic su Cerca.
Alex

SearchView non ha un clearFocus()nelle pagine API di Android, quindi questo non ha funzionato per me, ma un'altra soluzione ha fatto (vedi la mia risposta di seguito).
Azurespot,


12

Ho il caso, in cui il mio EditTextpuò essere posizionato anche in un AlertDialog, quindi la tastiera dovrebbe essere chiusa in caso di rifiuto. Il seguente codice sembra funzionare ovunque:

public static void hideKeyboard( Activity activity ) {
    InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
    View f = activity.getCurrentFocus();
    if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
        imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
    else 
        activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}

1
Questa soluzione è migliore perché non è necessario controllare quale EditText passa come parametro al metodo hideSoftInputFromWindow (). Funziona benissimo !!
Billyjoker,

12

Ho quasi provato tutte queste risposte, ho avuto alcuni problemi casuali soprattutto con la Samsung Galaxy S5.

Quello che finisco per forzare lo spettacolo e nascondermi, e funziona perfettamente:

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.