427 Stimmen

Wie kann man die Soft-Tastatur auf Android ausblenden, nachdem man außerhalb von EditText geklickt hat?

Ok, jeder weiß, dass man eine Tastatur verstecken muss, um sie zu implementieren:

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

Aber die große Frage ist, wie man die Tastatur ausblenden kann, wenn der Benutzer eine andere Stelle berührt oder auswählt, die kein EditText oder das SoftKeyboard?

Ich habe versucht, die onTouchEvent() bei meinen Eltern Activity aber das funktioniert nur, wenn der Benutzer außerhalb einer anderen Ansicht berührt und keine Bildlaufansicht vorhanden ist.

Ich habe versucht, einen Touch, Click, Focus Listener zu implementieren, ohne Erfolg.

Ich habe sogar versucht, meine eigene Scrollview zu implementieren, um Touch-Ereignisse abzufangen, aber ich kann nur die Koordinaten des Ereignisses und nicht die Ansicht angeklickt erhalten.

Gibt es eine Standardmethode, um dies zu tun? Beim iPhone war es wirklich einfach.

0 Stimmen

Mir wurde klar, dass nicht die Bildlaufleiste das Problem war, sondern die dort vorhandenen Etiketten. Die Ansicht ist ein vertikales Layout mit etwas wie: TextView, EditText,TextView,EditText, etc.. und die TextViews lassen nicht zu, dass der EditText den Fokus verliert und die Tastatur ausblendet

0 Stimmen

Sie können eine Lösung finden für getFields() hier: stackoverflow.com/questions/7790487/

0 Stimmen

Die Tastatur kann durch Drücken der Eingabetaste geschlossen werden, daher ist es fraglich, ob sich der Aufwand lohnt.

619voto

Navneeth G Punkte 7145

Das folgende Snippet blendet einfach die Tastatur aus:

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

Sie können dies in einer Hilfsklasse unterbringen, oder wenn Sie es innerhalb einer Aktivität definieren, vermeiden Sie den Aktivitätsparameter, oder rufen Sie hideSoftKeyboard(this) .

Das Schwierigste ist die Frage, wann man ihn anruft. Sie können eine Methode schreiben, die durch alle View in Ihrer Aktivität, und prüfen Sie, ob es sich um eine instanceof EditText wenn es sich nicht um die Registrierung eines setOnTouchListener zu dieser Komponente und alles wird sich fügen. Falls Sie sich fragen, wie man das macht, es ist eigentlich ganz einfach. Sie schreiben eine rekursive Methode wie die folgende, die Sie für alles Mögliche verwenden können, z. B. für die Einrichtung benutzerdefinierter Schriftarten usw... Hier ist die Methode

public void setupUI(View view) {

    // Set up touch listener for non-text box views to hide keyboard.
    if (!(view instanceof EditText)) {
        view.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(MyActivity.this);
                return false;
            }
        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupUI(innerView);
        }
    }
}

Das ist alles. Rufen Sie diese Methode einfach auf, nachdem Sie setContentView in Ihrer Tätigkeit. Falls Sie sich fragen, welchen Parameter Sie übergeben würden, es ist der id des übergeordneten Containers. Zuweisen einer id zu Ihrem übergeordneten Container wie

<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>

und rufen setupUI(findViewById(R.id.parent)) das ist alles.

Wenn Sie dies effektiv nutzen wollen, können Sie eine erweiterte Activity und fügen Sie diese Methode ein, und lassen Sie alle anderen Aktivitäten in Ihrer Anwendung diese Aktivität erweitern und ihre setupUI() において onCreate() Methode.

Ich hoffe, es hilft.

Wenn Sie mehr als 1 Aktivität verwenden, definieren Sie eine gemeinsame ID für das übergeordnete Layout wie <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

Erweitern Sie dann eine Klasse von Activity und definieren setupUI(findViewById(R.id.main_parent)) Innerhalb seiner OnResume() und erweitern Sie diese Klasse anstelle von ``Activity in your program


Hier ist eine Kotlin-Version der obigen Funktion:

@file:JvmName("KeyboardUtils")

fun Activity.hideSoftKeyboard() {
    currentFocus?.let {
        val inputMethodManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)!!
        inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0)
    }
}

0 Stimmen

Ich habe es nicht selbst getestet, aber es sieht so aus, als würde es funktionieren, und da es gute Bewertungen hat, werde ich die akzeptierte Antwort in diese ändern.

0 Stimmen

Das ist eine tolle Lösung, aber sie hat einen Mangel, zumindest für mich. Wenn ich den EditText erneut berühre, nachdem ich ihn geschlossen habe (indem ich außerhalb des EditTextes drücke), wird der Cursor an die vorherige Position zurückgesetzt (nicht an die Stelle, die ich berührt habe). Irgendwelche Ideen, um diesen Mini-Bug zu lösen?

0 Stimmen

Es funktioniert gr8 die Tastatur wird überall in der Anwendung verschwunden, aber das Problem, das ich konfrontiert bin, ist der Fokus bleibt immer noch auf die EditTextView, obwohl die Tastatur entlassen wird. Irgendeine Lösung für dieses Problem?

335voto

vida Punkte 4349

Sie können dies durch die folgenden Schritte erreichen:

  1. Machen Sie die übergeordnete Ansicht (Inhaltsansicht Ihrer Aktivität) klickbar und fokussierbar, indem Sie die folgenden Attribute hinzufügen

        android:clickable="true" 
        android:focusableInTouchMode="true" 
  2. Implementierung einer hideKeyboard()-Methode

        public void hideKeyboard(View view) {
            InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
  3. Zum Schluss setzen Sie den onFocusChangeListener Ihres Editetextes.

        edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideKeyboard(v);
                }
            }
        });

Wie in einem der Kommentare unten erwähnt, funktioniert dies möglicherweise nicht, wenn die übergeordnete Ansicht eine ScrollView ist. In diesem Fall kann der clickable und focusableInTouchMode auf der Ansicht direkt unter der ScrollView hinzugefügt werden.

76 Stimmen

Meiner Meinung nach ist dies die richtige Antwort. Weniger Code, keine unnötigen Iterationen...

19 Stimmen

Diese Antwort gefällt mir sehr gut. Eine Sache zu beachten ist, dass dies nicht für mich arbeiten, wenn das Hinzufügen clickable y focusableInTouchMode zu meiner Wurzel ScrollView Element. Ich musste dem direkten Elternteil meines EditText die ein LinearLayout .

0 Stimmen

@AdamJohns +1 Ich habe dieses Szenario getestet und Sie haben recht. Ich denke, der Grund dafür ist, dass ScrollView auch das Touch-Ereignis verarbeitet. Ich werde es als Anmerkung zur Antwort hinzufügen.

147voto

sumit sonawane Punkte 1365

Überschreiben Sie einfach den folgenden Code in der Aktivität

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

UPDATE:

Für den Fall, dass jemand die Kotlin-Version dieser Antwort benötigt:

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    if (currentFocus != null) {
        val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(activity!!.currentFocus!!.windowToken, 0)
    }
    return super.dispatchTouchEvent(ev)
}

11 Stimmen

Einfache Lösung: Fügen Sie eine Aktivität hinzu, und sie wird sich auch um das Fragment kümmern.

1 Stimmen

Eine andere Lösung besteht darin, BaseActivity zu erstellen und sie in allen Activities zu erweitern

3 Stimmen

Brillante Lösung

66voto

roepit Punkte 1093

Ich finde die akzeptierte Antwort etwas kompliziert.

Hier ist meine Lösung. Hinzufügen einer OnTouchListener zu Ihrem Hauptlayout, d. h.:

findViewById(R.id.mainLayout).setOnTouchListener(this)

und fügen Sie den folgenden Code in die onTouch-Methode ein.

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

Auf diese Weise müssen Sie nicht alle Ansichten durchgehen.

0 Stimmen

@roepit - im erhalten eine classCastexception für den Versuch, ein Layout in eine Ansicht zu werfen. bin ich etwas übersehen?

0 Stimmen

Können Sie irgendwo auf Ihren Code verweisen? Ich kann nicht sagen, was falsch ist, wenn ich nicht auf Ihr Layout und Aktivität / Fragment et cetera Code aussehen kann.

0 Stimmen

Die beste Antwort, die es gibt, aber ich versuche immer noch zu verstehen, wie es funktioniert.

44voto

Saurabh Pareek Punkte 7036

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 passen HIDE_IMPLICIT_ONLY an der Stelle von showFlag y 0 an der Stelle von hiddenFlag . Dadurch wird die Soft-Tastatur zwangsweise geschlossen.

3 Stimmen

Danke, es ist Arbeit..... vor allem hatte ich versucht, aber es funktioniert nicht, während ich m immer Wert aus Dialogbox editext Text nd Schließen Dialogbox...

0 Stimmen

Danke, das funktioniert nur, und es ist viel sauberer als die anderen oben! +1

0 Stimmen

Es funktioniert wie erwartet, vielen Dank für Ihre Lösung +1

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X