android close keyboard - Schließen / verbergen Sie die Android Soft-Tastatur




15 Answers

Um diesen Wahnsinn zu klären, möchte ich mich zunächst bei allen Android-Nutzern für die geradezu lächerliche Behandlung der Soft-Tastatur von Google entschuldigen. Der Grund, warum es so viele Antworten gibt, jede für sich, für die gleiche einfache Frage ist, dass diese API, wie viele andere in Android, fürchterlich gestaltet ist. Ich kann mir keine höfliche Art und Weise vorstellen, es auszudrücken.

Ich möchte die Tastatur ausblenden. Ich erwarte, Android die folgende Aussage zu geben: Keyboard.hide() . Das Ende. Vielen Dank. Aber Android hat ein Problem. Sie müssen den InputMethodManager , um die Tastatur auszublenden. OK, gut, das ist die API von Android für die Tastatur. ABER! Sie benötigen einen Context , um auf das IMM zugreifen zu können. Jetzt haben wir ein Problem. Ich möchte die Tastatur vor einer statischen oder Dienstprogrammklasse ausblenden, die keinen Context hat oder benötigt. oder VIEL schlechter ist, dass das IMM verlangt, dass Sie angeben, aus welcher View (oder noch schlimmer, aus welchem Window ) Sie die Tastatur HERAUS ausblenden möchten.

Dies macht das Verstecken der Tastatur so schwierig. Sehr geehrtes Google: Wenn ich nach dem Rezept für einen Kuchen RecipeProvider , gibt es keinen RecipeProvider auf der Erde, der sich weigern würde, mir das Rezept zur Verfügung zu stellen, es sei denn, ich antworte zuerst, WENN der Kuchen von AND gegessen wird und wo er gegessen wird !!

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

Ich habe eine statische Dienstprogrammmethode erstellt, die den Job sehr zuverlässig erledigen kann, vorausgesetzt, Sie rufen sie aus 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 beim Aufruf aus einer Activity funktioniert! Die obige Methode ruft getCurrentFocus der getCurrentFocus auf, um das richtige Fenstertoken abzurufen.

Angenommen, Sie möchten die Tastatur vor einem in einem DialogFragment gehosteten DialogFragment ? Sie können die Methode oben nicht dafür verwenden:

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

Dies funktioniert nicht, da Sie einen Verweis auf die Host- Activity des Fragment , die keine fokussierte Kontrolle hat, während das Fragment angezeigt wird! Beeindruckend! Um die Tastatur vor Fragmenten zu verstecken, greife ich auf die untergeordnete Ebene, häufiger und hässlicher:

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

Nachfolgend finden Sie einige zusätzliche Informationen, die aus mehr Zeit bei der Suche nach dieser Lösung gewonnen wurden:

Über windowSoftInputMode

Es gibt noch einen weiteren Streitpunkt, den Sie beachten sollten. Standardmäßig weist Android dem ersten EditText oder fokussierbaren Steuerelement in Ihrer Activity automatisch den Anfangsfokus zu. Daraus folgt natürlich, dass die InputMethod (normalerweise die Soft-Tastatur) auf das Fokusereignis reagiert, indem sie sich selbst anzeigt. 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"/>

Es scheint fast unglaublich, dass die Tastatur nicht daran focusable="false" beim Berühren des Steuerelements zu focusable="false" (es sei denn, dem Steuerelement sind focusable="false" und / oder focusableInTouchMode="false" zugewiesen). Offenbar gilt die Einstellung windowSoftInputMode nur für automatische Fokusereignisse, nicht für Fokusereignisse, die von Berührungsereignissen ausgelöst werden.

stateAlwaysHidden ist daher SEHR schlecht benannt. Es sollte stattdessen vielleicht ignoreInitialFocus heißen.

Hoffe das hilft.

UPDATE: Weitere Möglichkeiten, ein Fenstertoken zu erhalten

Wenn keine fokussierte Ansicht vorliegt (z. B. wenn Sie gerade Fragmente geändert haben), gibt es andere Ansichten, die ein nützliches Fenstertoken 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();

Ein Fragmentfragment als Parameter gegeben:

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

Ausgehend von Ihrem Inhaltskörper:

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

UPDATE 2: Löschen Sie den Fokus, um zu vermeiden, dass die Tastatur erneut angezeigt wird, wenn Sie die App im Hintergrund öffnen

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

view.clearFocus();

on button

Ich habe einen EditText und einen Button in meinem Layout.

Nach dem Schreiben in das Bearbeitungsfeld und dem Klicken auf die Button möchte ich die virtuelle Tastatur ausblenden. Ich gehe davon aus, dass dies ein einfacher Code ist, aber wo finde ich ein Beispiel dafür?




Auch zum Ausblenden der Soft-Tastatur ist Folgendes hilfreich:

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

Dies kann verwendet werden, um die Soft-Tastatur zu unterdrücken, bis der Benutzer die editText-Ansicht tatsächlich berührt.




Die Lösung von Meier funktioniert auch für mich. In meinem Fall ist die oberste Ebene meiner App ein tabHost, und ich möchte das Schlüsselwort ausblenden, wenn Sie zwischen Registerkarten wechseln. Ich erhalte das Fenstertoken aus der tabHost-Ansicht.

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



Update: Ich weiß nicht, warum diese Lösung nicht mehr funktioniert (ich habe gerade auf Android 23 getestet). Bitte verwenden Sie stattdessen die Lösung von Saurabh Pareek . Hier ist es:

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

Alte Antwort:

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



Wenn alle anderen Antworten hier nicht für Sie funktionieren, können Sie die Tastatur manuell steuern.

Erstellen Sie eine Funktion, mit der einige Eigenschaften von EditText verwaltet werden:

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

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

EditText Sie dann sicher, dass Sie bei onFocus des EditText die Tastatur öffnen / schließen:

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

Wenn Sie nun die Tastatur manuell öffnen möchten, rufen Sie Folgendes auf:

setEditTextFocus(true);

Und zum Schlußruf:

setEditTextFocus(false);



Von dieser Suche habe ich hier eine Antwort gefunden, die für mich funktioniert

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



Das sollte funktionieren:

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



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



Alternativ zu dieser Rundum-Lösung : Wenn Sie die Soft-Tastatur von überall aus schließen möchten, ohne einen Verweis auf das Feld (EditText) zu haben, das zum Öffnen der Tastatur verwendet wurde, dies jedoch tun wollte, wenn das Feld fokussiert war, können Sie es verwenden dies (aus einer Aktivität):

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



Die obigen Antworten funktionieren für verschiedene Szenarien. Wenn Sie jedoch die Tastatur in einer Ansicht ausblenden möchten und versuchen, den richtigen Kontext zu ermitteln, versuchen Sie Folgendes:

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

und um den Kontext vom Konstruktor abzurufen :)

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



So machen Sie es in Mono für Android (AKA MonoDroid)

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



Fügen Sie Ihrer Aktivität android:windowSoftInputMode="stateHidden"in Manifest-Datei hinzu. Beispiel:

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



Für meinen Fall habe ich eine SearchView in der Aktionsleiste verwendet. Nachdem ein Benutzer eine Suche ausgeführt hat, öffnet sich die Tastatur erneut.

Mit dem InputMethodManager wurde die Tastatur nicht geschlossen. Ich musste clearFocus einstellen und den Fokus der Suchansicht auf false setzen:

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



In einigen Fällen können diese Methoden mit Ausnahme aller anderen funktionieren. Das spart meinen Tag :)

public static void hideSoftKeyboard(Activity activity) {
    if (activity != null) {
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (activity.getCurrentFocus() != null && inputManager != null) {
            inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
            inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

public static void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}



Verwenden Sie einfach diesen optimierten Code in Ihrer Aktivität:

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



Related