Domanda Chiudi / nascondi la tastiera virtuale di Android


ho un EditText e a Button nel mio layout.

Dopo aver scritto nel campo di modifica e facendo clic sul Button, Voglio nascondere la tastiera virtuale. Presumo che questo è un semplice pezzo di codice, ma dove posso trovare un esempio di esso?


3085


origine


risposte:


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

Voglio nascondere la tastiera. Mi aspetto di fornire a Android la seguente dichiarazione: Keyboard.hide(). Fine. Grazie mille. Ma Android ha un problema. Devi usare il InputMethodManager per nascondere la tastiera. OK, bene, questa è l'API di Android per la tastiera. MA! È necessario avere un Context per poter accedere all'IMM. Ora abbiamo un problema Potrei voler nascondere la tastiera da una classe statica o utility che non ne ha bisogno o ne ha bisogno Context. o E, peggio, l'IMM richiede che tu specifichi cosa View (o peggio ancora, cosa Window) si desidera nascondere la tastiera FROM.

Questo è ciò che rende la tastiera così difficile da nascondere. Gentile Google: quando cerco la ricetta per una torta, non c'è RecipeProvider sulla Terra che si rifiuterebbe di fornirmi la ricetta a meno che non rispondo per prima cosa CHI la torta sarà mangiata da AND dove sarà mangiata !!

Questa triste storia si conclude con la brutta verità: per nascondere la tastiera Android, ti verrà richiesto di fornire 2 forme di identificazione: a Context e uno a View o a Window.

Ho creato un metodo di utilità statica che può fare il lavoro MOLTO solidamente, 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);
}

Essere consapevoli del fatto che questo metodo di utilità funziona SOLO quando chiamato da un Activity! Il metodo sopra chiama getCurrentFocus del bersaglio Activity per recuperare il token della finestra corretta.

Ma supponiamo di voler nascondere la tastiera da un EditText ospitato in a DialogFragment? Non è possibile utilizzare il metodo sopra per quello:

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

Questo non funzionerà perché passerai un riferimento al file Fragmentl'ospite Activity, che non avrà controllo focalizzato mentre il Fragment è 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 ricavate da più sprechi di tempo a inseguire questa soluzione:

Informazioni su windowSoftInputMode

C'è ancora un altro punto di discussione di cui essere a conoscenza. Per impostazione predefinita, Android assegna automaticamente il focus iniziale al primo EditText o controllo focalizzabile nel tuo Activity. Ne consegue naturalmente che InputMethod (tipicamente la tastiera virtuale) risponderà all'evento di messa a fuoco mostrandosi. Il windowSoftInputMode attributo in AndroidManifest.xml, quando impostato su stateAlwaysHidden, indica alla tastiera di ignorare questa messa a fuoco iniziale assegnata automaticamente.

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

Quasi incredibilmente, sembra non fare nulla per impedire l'apertura della tastiera quando si tocca il controllo (a meno che non focusable="false" e / o focusableInTouchMode="false" sono assegnati al controllo). Apparentemente, l'impostazione windowSoftInputMode si applica solo agli eventi di messa a fuoco automatica, non per mettere a fuoco gli eventi attivati ​​da eventi di tocco.

Perciò, stateAlwaysHidden è MOLTO mal indicato. Dovrebbe forse essere chiamato ignoreInitialFocus anziché.

Spero che questo ti aiuti.


AGGIORNARE: Altri modi per ottenere un token finestra

Se non c'è una vista focalizzata (ad esempio può succedere se hai appena cambiato i frammenti), ci sono altre viste che forniranno un gettone finestra utile.

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

All'interno di una classe frammento:

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

Dato un frammento fragment come parametro:

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

A partire dal tuo corpo contenuto:

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

AGGIORNAMENTO 2: Cancella messa a fuoco per evitare di mostrare nuovamente la tastiera se si apre l'app dallo sfondo

Aggiungi questa linea alla fine del metodo:

view.clearFocus();


1004



Puoi forzare Android a nascondere la tastiera virtuale usando il InputMethodManager, chiamando hideSoftInputFromWindowpassando il token della finestra che contiene la tua 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_ONLY come secondo parametro per assicurarsi di nascondere la tastiera solo quando l'utente non ha forzato esplicitamente la visualizzazione (tenendo premuto il menu).

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


4170



Utile anche per nascondere la tastiera virtuale è:

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

Questo può essere usato per sopprimere la tastiera virtuale finché l'utente non tocca effettivamente la vista editText.


741



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_ONLY nella posizione di showFlag e 0 nella posizione di hiddenFlag. Chiuderà forzatamente la tastiera morbida.


294



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 passa da una scheda all'altra: ottengo il token della finestra dal menu Visualizza.

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

128



Si prega di provare questo sotto il codice in onCreate()

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

115



Aggiornare: Non so perché questa soluzione non funzioni più (ho appena provato su Android 23). Si prega di utilizzare la soluzione di Saurabh Pareek anziché. 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);

107



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

63