Schließen / verstecken Sie die Android-Soft-Tastatur



Answers

Um diesen Wahnsinn zu verdeutlichen, möchte ich mich im Namen aller Android-Nutzer für die geradezu lächerliche Behandlung der weichen Tastatur durch Google entschuldigen. Der Grund, warum es so viele Antworten gibt, jede für die gleiche einfache Frage, ist, weil diese API, wie viele andere in Android, entsetzlich gestaltet ist. Ich kann mir keine höfliche Art vorstellen, es zu sagen.

Ich möchte die Tastatur verstecken. Ich erwarte, Android mit der folgenden Anweisung zu versehen: Keyboard.hide() . Das Ende. Vielen Dank. Aber Android hat ein Problem. Sie müssen den InputMethodManager , um die Tastatur auszublenden. OK, gut, das ist Androids API auf der Tastatur. ABER! Sie benötigen einen Context , um Zugriff auf das IMM zu erhalten. Jetzt haben wir ein Problem. Ich möchte vielleicht die Tastatur aus einer statischen oder Dienstprogramm-Klasse verstecken, die keinen Context benötigt oder benötigt. Oder noch schlimmer, das IMM erfordert, dass Sie angeben, welche View (oder schlimmer noch, welches Window ) Sie die Tastatur von der Tastatur verbergen möchten.

Das macht das Ausblenden der Tastatur so schwierig. Lieber Google: Wenn ich nach dem Rezept für einen Kuchen suche, gibt es keinen RecipeProvider auf der Erde, der sich weigern würde, mir das Rezept zu geben, wenn ich nicht zuerst antworte, WER den Kuchen essen wird UND wo er gegessen wird !!

Diese traurige Geschichte endet mit der hässlichen Wahrheit: Um die Android-Tastatur zu verstecken, müssen Sie zwei Arten der Identifikation Context : einen Context und entweder eine View oder ein Window .

Ich habe eine statische Hilfsmethode erstellt, die die Arbeit SEHR stabil erledigt, vorausgesetzt, Sie rufen sie von einer 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);
}

Beachten Sie, dass diese Dienstprogrammmethode NUR funktioniert, wenn sie von einer Activity aufgerufen wird! Die obige Methode ruft getCurrentFocus der getCurrentFocus auf, um das richtige Fenster-Token abzurufen.

Angenommen, Sie möchten die Tastatur vor einem EditText verbergen, der in einem EditText gehostet DialogFragment ? Sie können die obige Methode nicht dafür verwenden:

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

Dies wird nicht funktionieren, da du einen Verweis auf die Host- Activity des Fragment Activity , der keine fokussierte Kontrolle hat, während das Fragment angezeigt wird! Beeindruckend! Um also die Tastatur vor Fragmenten zu verbergen, greife ich auf die niedrigere, häufigere und hässlichere Ebene zurück:

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

Im Folgenden finden Sie einige zusätzliche Informationen, die sich aus der Zeit ergeben haben, die mit der Verfolgung dieser Lösung verschwendet wurde:

Über windowSoftInputMode

Es gibt noch einen weiteren Streitpunkt, der beachtet werden muss. Standardmäßig weist Android dem ersten EditText oder fokussierbaren Steuerelement in Ihrer Activity den ersten Fokus zu. Daraus folgt natürlich, dass InputMethod (normalerweise die Soft-Tastatur) auf das Fokus-Ereignis reagiert, indem es sich selbst zeigt. windowSoftInputMode das windowSoftInputMode Attribut in AndroidManifest.xml auf stateAlwaysHidden , weist es die Tastatur an, diesen automatisch zugewiesenen anfänglichen Fokus zu ignorieren.

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

Fast unglaublich scheint es nichts zu tun, um zu verhindern, dass sich die Tastatur öffnet, wenn Sie das Steuerelement berühren (es sei denn, focusable="false" und / oder focusableInTouchMode="false" sind dem Steuerelement zugewiesen). Offenbar gilt die Einstellung windowSoftInputMode nur für automatische Fokusereignisse, nicht um Ereignisse zu fokussieren, die von Berührungsereignissen ausgelöst werden.

Daher ist " stateAlwaysHidden SEHR schlecht benannt. Es sollte stattdessen ignoreInitialFocus werden.

Hoffe das hilft.

UPDATE: Weitere Möglichkeiten, ein Fenster-Token zu erhalten

Wenn es keine fokussierte Ansicht gibt (zB wenn Sie nur Fragmente geändert haben), gibt es andere Ansichten, die ein nützliches Fenster-Token liefern.

Dies sind Alternativen für den obigen Code if (view == null) view = new View(activity); Diese beziehen sich nicht explizit auf Ihre Aktivität.

Innerhalb einer Fragmentklasse:

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

Gegeben ein Fragmentfragment als Parameter:

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

Ausgehend von Ihrem Inhaltskörper:

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

UPDATE 2: Deaktivieren Sie den Fokus, um zu vermeiden, dass die Tastatur erneut angezeigt wird, wenn Sie die App aus dem Hintergrund öffnen

Fügen Sie diese Zeile am Ende der Methode hinzu:

view.clearFocus();

Question

Ich habe einen EditText und einen Button in meinem Layout.

Nachdem ich in das Bearbeitungsfeld geschrieben und auf den Button geklickt habe, möchte ich die virtuelle Tastatur verstecken. Ich nehme an, dass dies ein einfacher Code ist, aber wo finde ich ein Beispiel dafür?




Saurabh Pareek hat die beste Antwort bisher.

Könnte auch die richtigen Flags verwenden.

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

Beispiel für die tatsächliche Verwendung

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



Bitte versuchen Sie es unter code in oncreate ()

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




Ich verwende eine benutzerdefinierte Tastatur, um eine Hex-Zahl einzugeben, damit ich nicht die IMM-Tastatur anzeigen lassen kann ...

In v3.2.4_r1 wurde setSoftInputShownOnFocus(boolean show) hinzugefügt, um das Wetter zu steuern oder um die Tastatur nicht anzuzeigen, wenn ein TextView den Fokus erhält, aber es ist immer noch versteckt, so dass die Reflektion verwendet werden muss:

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

Für ältere Versionen habe ich mit einem OnGlobalLayoutListener , der mit Hilfe eines ViewTreeObserver aus meiner Root-Ansicht hinzugefügt wurde und dann überprüft, ob die Tastatur so dargestellt wird, sehr gute (aber bei weitem nicht perfekte) Ergebnisse:

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

Diese letzte Lösung zeigt möglicherweise die Tastatur für einen Bruchteil einer Sekunde an und verwirrt mit den Auswahlpunkten.

Wenn auf der Tastatur der Vollbildmodus angezeigt wird, wird onGlobalLayout nicht aufgerufen. Um dies zu vermeiden, verwenden Sie TextView#setImeOptions(int) oder in der TextView XML-Deklaration:

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

Update: Habe gerade herausgefunden, welche Dialoge die Tastatur nie anzeigen und in allen Versionen funktionieren:

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



Simple and Easy to use method, just call hideKeyboardFrom(YourActivity.this); to hide keyboard

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



Just use this optimized code in your activity:

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



Die kurze Antwort

OnClick in Ihrem OnClick Listener die onEditorAction des EditText mit IME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

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

Der Drilldown

Ich finde, dass diese Methode besser, einfacher und besser mit dem Designmuster von Android abgestimmt ist. In dem einfachen Beispiel oben (und normalerweise in den meisten Fällen) haben Sie einen EditText , der / der den Fokus hatte und normalerweise auch derjenige war, der die Tastatur aufruft (es ist definitiv in der Lage, sie aufzurufen) viele häufige Szenarien). Auf die gleiche Weise sollte es die Tastatur freigeben, was normalerweise durch eine ImeAction erledigt werden ImeAction . Sehen Sie sich einmal an, wie sich ein EditText mit android:imeOptions="actionDone" verhält, Sie wollen dasselbe Verhalten auf die gleiche Weise erreichen.

Überprüfen Sie diese verwandte Antwort




If you want to close the soft keyboard during a unit or functional test, you can do so by clicking the "back button" from your test:

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

I put "back button" in quotes, since the above doesn't trigger the onBackPressed() for the Activity in question. It just closes the keyboard.

Make sure to pause for a little while before moving on, since it takes a little while to close the back button, so subsequent clicks to Views, etc., won't be registered until after a short pause (1 second is long enough ime).




For my case, I was using the a SearchView in the actionbar. After a user performs a search, the keyboard would pop open again.

Using the InputMethodManager did not close the keyboard. I had to clearFocus and set the focusable of the search view to false:

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



Alternativ zu dieser allumfassenden Lösung , wenn Sie die Soft-Tastatur von überall schließen wollten, ohne einen Verweis auf das Feld (EditText) zu haben, das zum Öffnen der Tastatur verwendet wurde, aber trotzdem das Feld fokussieren wollte, könnten Sie es verwenden dies (von einer Aktivität):

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



This worked for me for all the bizarre keyboard behavior

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



Ich habe eine weitere Lösung, um die Tastatur zu verstecken:

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

Hier übergeben Sie HIDE_IMPLICIT_ONLY an der Position von showFlag und 0 an der Position von hiddenFlag . Es schließt die Soft-Tastatur mit Gewalt.




Thanks to this SO answer , I derived the following which, in my case, works nicely when scrolling through the the fragments of a 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);
    }
}



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



Ich habe den Fall, wo ich EditTextauch in einem liegen kann AlertDialog, also sollte die Tastatur beim Entlassen geschlossen sein. Der folgende Code scheint überall zu funktionieren:

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



Related