Ok, jeder weiß, dass zum Implementieren einer Tastatur Folgendes implementiert werden muss:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
Aber die große Sache hier ist, wie man die Tastatur versteckt, wenn der Benutzer einen anderen Ort berührt oder auswählt, der kein EditText
SoftKeyboard ist?
Ich habe versucht, das onTouchEvent()
für meine Eltern zu verwenden, Activity
aber das funktioniert nur, wenn der Benutzer eine andere Ansicht berührt und keine Bildlaufansicht vorhanden ist.
Ich habe erfolglos versucht, einen Touch-, Click- und Focus-Listener zu implementieren.
Ich habe sogar versucht, meine eigene Bildlaufansicht zu implementieren, um Berührungsereignisse abzufangen, aber ich kann nur die Koordinaten des Ereignisses abrufen und nicht die angeklickte Ansicht.
Gibt es einen Standardweg, um dies zu tun? im iPhone war es wirklich einfach.
quelle
getFields()
hier: stackoverflow.com/questions/7790487/…Antworten:
Das folgende Snippet verbirgt einfach die Tastatur:
Sie können dies in einer Dienstprogrammklasse ablegen oder, wenn Sie es innerhalb einer Aktivität definieren, den Aktivitätsparameter vermeiden oder aufrufen
hideSoftKeyboard(this)
.Der schwierigste Teil ist, wann man es nennt. Sie können eine Methode schreiben, die alle
View
in Ihrer Aktivität durchläuft , und prüfen, ob es sich um eine Methode handelt, dieinstanceof EditText
nichtsetOnTouchListener
für diese Komponente registriert ist , und alles passt zusammen. Falls Sie sich fragen, wie das geht, ist es in der Tat ganz einfach. Hier ist, was Sie tun, Sie schreiben eine rekursive Methode wie die folgende, in der Tat können Sie diese verwenden, um alles zu tun, wie benutzerdefinierte Schriften einzurichten usw. ... Hier ist die MethodeDas ist alles, rufen Sie diese Methode einfach nach Ihnen
setContentView
in Ihrer Aktivität auf. Wenn Sie sich fragen, welchen Parameter Sie übergeben würden, handelt es sichid
um den übergeordneten Container. Weisen Sieid
Ihrem übergeordneten Container einen zu<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>
und ruf an
setupUI(findViewById(R.id.parent))
, das ist alles.Wenn Sie dies effektiv nutzen möchten, können Sie eine erweiterte
Activity
Methode erstellen und diese Methode einfügen. Alle anderen Aktivitäten in Ihrer Anwendung können diese Aktivität erweitern undsetupUI()
in deronCreate()
Methode aufrufen .Ich hoffe es hilft.
Wenn Sie mehr als eine Aktivität verwenden, definieren Sie die allgemeine ID für das übergeordnete Layout wie
<RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Erweitern Sie dann eine Klasse aus
Activity
und definieren SiesetupUI(findViewById(R.id.main_parent))
Innerhalb ihrerOnResume()
und erweitern Sie diese Klasse anstelle von `` Activityin your program
Hier ist eine Kotlin-Version der obigen Funktion:
quelle
if(activity.getCurrentFocus() != null) {...}
OnTouchListener
für sie festlegen müssen. Sie können diese Logik einfach in einer Stammansicht festlegenViewGroup.onInterceptTouchEvent(MotionEvent)
.Sie können dies erreichen, indem Sie die folgenden Schritte ausführen:
Machen Sie die übergeordnete Ansicht (Inhaltsansicht Ihrer Aktivität) anklickbar und fokussierbar, indem Sie die folgenden Attribute hinzufügen
Implementieren Sie eine hideKeyboard () -Methode
Zuletzt legen Sie den onFocusChangeListener Ihres Edittextes fest.
Wie in einem der folgenden Kommentare ausgeführt, funktioniert dies möglicherweise nicht, wenn die übergeordnete Ansicht eine ScrollView ist. In diesem Fall kann der anklickbare und fokussierbare InTouchMode in der Ansicht direkt unter der ScrollView hinzugefügt werden.
quelle
clickable
undfocusableInTouchMode
zu meinem Stammelement nicht funktioniert hatScrollView
. Ich musste dem direkten Elternteil von mir hinzufügen,EditText
welches ein warLinearLayout
.Überschreiben Sie einfach den folgenden Code in Aktivität
quelle
Ich finde die akzeptierte Antwort etwas kompliziert.
Hier ist meine Lösung. Fügen Sie
OnTouchListener
Ihrem Hauptlayout ein hinzu, dh:und fügen Sie den folgenden Code in die onTouch-Methode ein.
Auf diese Weise müssen Sie nicht alle Ansichten durchlaufen.
quelle
android:onClick="stealFocusFromEditTexts"
der XML- Datei der übergeordneten Ansicht und dannpublic void stealFocusFromEditTexts(View view) {}
ihrer Aktivität hinzu. Die On-Click-Methode muss nichts tun, sie muss nur vorhanden sein, damit die übergeordnete Ansicht fokussierbar / auswählbar ist. Dies ist erforderlich, um dem Kind den Fokus zu stehlen. EditTextIch habe noch eine Lösung, um die Tastatur zu verstecken:
Hier
HIDE_IMPLICIT_ONLY
an der Position vonshowFlag
und0
an der Position von passierenhiddenFlag
. Dadurch wird die Softtastatur gewaltsam geschlossen.quelle
Nun, ich schaffe es, das Problem etwas zu lösen. Ich habe das dispatchTouchEvent bei meiner Aktivität überschrieben. Dort verwende ich Folgendes, um die Tastatur auszublenden.
BEARBEITEN : Die Methode getFields () ist nur eine Methode, die ein Array mit den Textfeldern in der Ansicht zurückgibt. Um zu vermeiden, dass dieses Array bei jeder Berührung erstellt wird, habe ich ein statisches Array namens sFields erstellt, das bei der Methode getFields () zurückgegeben wird. Dieses Array wird mit den onStart () -Methoden initialisiert, z.
sFields = new EditText[] {mUserField, mPasswordField};
Es ist nicht perfekt. Die Zeit für das Drag-Ereignis basiert nur auf Heuristiken, sodass sie manchmal nicht ausgeblendet wird, wenn lange Clics ausgeführt werden. Außerdem habe ich eine Methode erstellt, um alle editTexts pro Ansicht abzurufen. Andernfalls wird die Tastatur beim Klicken auf einen anderen EditText ausgeblendet und angezeigt.
Trotzdem sind sauberere und kürzere Lösungen willkommen
quelle
getFields()
Methode enthält, um anderen in Zukunft zu helfen ? Es muss nicht genau sein, nur ein Beispiel mit vielleicht nur einigen Kommentaren, die darauf hinweisen, dass es ein Array vonEditText
Objekten zurückgibt .Verwenden Sie OnFocusChangeListener .
Zum Beispiel:
Update : Sie können auch
onTouchEvent()
Ihre Aktivität überschreiben und die Koordinaten der Berührung überprüfen. Wenn sich die Koordinaten außerhalb von EditText befinden, blenden Sie die Tastatur aus.quelle
Ich habe dispatchTouchEvent in Activity implementiert, um dies zu tun:
und ich habe es getestet, funktioniert perfekt!
quelle
Eine mehr Kotlin & Material Design- Methode mit TextInputEditText (dieser Ansatz ist auch kompatibel mit EditTextView ) ...
1.Machen Sie die übergeordnete Ansicht (Inhaltsansicht Ihrer Aktivität / Ihres Fragments) anklickbar und fokussierbar, indem Sie die folgenden Attribute hinzufügen
2.Erstellen Sie eine Erweiterung für alle Ansichten (z. B. in einer ViewExtension.kt-Datei):
3.Erstellen Sie einen BaseTextInputEditText, der von TextInputEditText erbt. Implementieren Sie die Methode onFocusChanged, um die Tastatur auszublenden, wenn die Ansicht nicht fokussiert ist:
4. Rufen Sie einfach Ihre brandneue benutzerdefinierte Ansicht in Ihrem XML auf:
Das ist alles. Sie müssen Ihre Controller (Fragment oder Aktivität) nicht ändern , um diesen sich wiederholenden Fall zu behandeln.
quelle
Überschreiben Sie das öffentliche boolesche dispatchTouchEvent (MotionEvent-Ereignis) in einer beliebigen Aktivität (oder erweitern Sie die Aktivitätsklasse).
Und das ist alles was Sie tun müssen
quelle
Ich habe die Lösung von Andre Luis IM modifiziert. Ich habe diese erreicht:
Ich habe eine Dienstprogrammmethode erstellt, um die Softtastatur genauso zu verbergen wie Andre Luiz IM:
Aber anstatt für jede Ansicht einen OnTouchListener zu registrieren, der eine schlechte Leistung bietet, habe ich den OnTouchListener nur für die Stammansicht registriert. Da das Ereignis sprudelt, bis es verbraucht ist (EditText ist eine der Ansichten, die es standardmäßig verbrauchen), liegt es daran, dass es nicht verbraucht wurde, wenn es in der Stammansicht ankommt. Deshalb schließe ich die Softtastatur.
quelle
Ich bin mir bewusst, dass dieser Thread ziemlich alt ist, die richtige Antwort gültig zu sein scheint und es viele funktionierende Lösungen gibt, aber ich denke, dass der unten angegebene Ansatz einen zusätzlichen Vorteil in Bezug auf Effizienz und Eleganz haben könnte.
Ich benötige dieses Verhalten für alle meine Aktivitäten, daher habe ich eine Klasse CustomActivity erstellt, die von der Klasse Activity erbt, und die Funktion dispatchTouchEvent "verknüpft" . Es sind hauptsächlich zwei Bedingungen zu beachten:
Das ist mein Ergebnis:
Randnotiz: Zusätzlich ordne ich diese Attribute der Stammansicht zu, um den Fokus auf jedes Eingabefeld zu löschen und zu verhindern, dass Eingabefelder beim Aktivitätsstart den Fokus erhalten (wodurch die Inhaltsansicht zum "Fokusfänger" wird):
quelle
Ich mochte den Ansatz
dispatchTouchEvent
von htafoya, anzurufen, aber:Also habe ich diese etwas einfachere Lösung gemacht:
Es gibt einen Nachteil:
Wenn Sie von einer
EditText
zur anderenEditText
wechseln, wird die Tastatur ausgeblendet und erneut angezeigt. In meinem Fall ist dies erwünscht, da angezeigt wird, dass Sie zwischen zwei Eingabekomponenten gewechselt haben.quelle
Bitte: Ich erkenne, dass ich keine Schlagkraft habe, aber bitte nehmen Sie meine Antwort ernst.
Problem: Schließen Sie die Softtastatur, wenn Sie von der Tastatur wegklicken oder Text mit minimalem Code bearbeiten.
Lösung: Externe Bibliothek namens Butterknife.
Einzeilige Lösung:
Lesbarere Lösung:
Erläuterung: Binden Sie OnClick Listener an die übergeordnete XML-Layout-ID der Aktivität, damit bei jedem Klick auf das Layout (nicht auf den Bearbeitungstext oder die Tastatur) der Codeausschnitt ausgeführt wird, der die Tastatur verbirgt.
Beispiel: Wenn Ihre Layoutdatei R.layout.my_layout und Ihre Layout-ID R.id.my_layout_id lautet, sollte Ihr Butterknife-Bindungsaufruf folgendermaßen aussehen:
Link zur Butterknife-Dokumentation: http://jakewharton.github.io/butterknife/
Plug: Butterknife wird Ihre Android-Entwicklung revolutionieren. Denke darüber nach.
Hinweis: Das gleiche Ergebnis kann ohne die Verwendung einer externen Bibliothek Butterknife erzielt werden. Stellen Sie einfach einen OnClickListener wie oben beschrieben auf das übergeordnete Layout ein.
quelle
In Kotlin können wir Folgendes tun. Es ist nicht erforderlich, alle Ansichten zu wiederholen. Es wird auch für Fragmente funktionieren.
quelle
Hier ist eine weitere Variation der Antwort von fje, die sich mit den von sosite aufgeworfenen Fragen befasst.
Die Idee hier ist, sowohl die Abwärts- als auch die Aufwärtsaktionen in der Aktivitätsmethode zu behandeln
dispatchTouchEvent
. Bei der Abwärtsaktion notieren wir uns die aktuell fokussierte Ansicht (falls vorhanden) und ob sich die Berührung darin befand, und speichern beide Informationen für später.Bei der Aufwärtsaktion versenden wir zuerst, damit eine andere Ansicht möglicherweise den Fokus erhält. Wenn danach die aktuell fokussierte Ansicht die ursprünglich fokussierte Ansicht ist und sich die Abwärtsberührung in dieser Ansicht befand, lassen wir die Tastatur offen.
Wenn sich die aktuell fokussierte Ansicht von der ursprünglich fokussierten Ansicht unterscheidet und eine ist
EditText
, lassen wir auch die Tastatur offen.Ansonsten schließen wir es.
Zusammenfassend funktioniert dies also wie folgt:
EditText
bleibt die Tastatur geöffnetEditText
zu einem anderenEditText
bleibt die Tastatur geöffnet (schließt / öffnet nicht)EditText
, das kein anderes istEditText
, die , wird die Tastatur geschlossenEditText
Taste drücken , um die Kontextaktionsleiste aufzurufen (mit den Schaltflächen Ausschneiden / Kopieren / Einfügen), bleibt die Tastatur geöffnet, obwohl die UP-Aktion außerhalb des Fokus ausgeführt wurdeEditText
(der nach unten verschoben wurde, um Platz für das CAB zu schaffen). . Beachten Sie jedoch, dass beim Tippen auf eine Schaltfläche im CAB die Tastatur geschlossen wird. Das kann wünschenswert sein oder nicht; Wenn Sie aus einem Feld ausschneiden / kopieren und in ein anderes einfügen möchten, ist dies der Fall. Wenn Sie wieder in dasselbe einfügen möchtenEditText
, wäre dies nicht der Fall.Wenn sich der Fokus
EditText
am unteren Bildschirmrand befindet und Sie lange auf einen Text klicken, um ihn auszuwählen,EditText
bleibt der Fokus erhalten, und daher wird die Tastatur wie gewünscht geöffnet, da bei der Abwärtsaktion die Option "Berühren ist innerhalb der Sichtgrenzen" ausgeführt wird , nicht die Up-Aktion.quelle
Es ist zu einfach. Machen Sie Ihr aktuelles Layout durch diesen Code anklickbar und fokussierbar:
Schreiben Sie dann eine Methode und einen OnClickListner für dieses Layout, sodass beim Berühren des obersten Layouts eine Methode aufgerufen wird, in die Sie Code schreiben, um die Tastatur zu schließen. Das Folgende ist der Code für beide; // du musst dies in OnCreate () schreiben
vom Listener aufgerufene Methode: -
quelle
Ich finde das akzeptierte Antwortbit komplex für diese einfache Anforderung. Hier ist, was für mich ohne Probleme funktioniert hat.
quelle
NestedScrollView
komplexe Layouts verwenden, lesen Sie die akzeptierte Antwort: stackoverflow.com/a/11656129/2914140 . Sie sollten wissen, dass andere Behälter Berührungen verbrauchen können.Es gibt einen einfacheren Ansatz, der auf dem gleichen Problem des iPhone basiert. Überschreiben Sie einfach das Layout des Hintergrunds bei einem Berührungsereignis, in dem der Bearbeitungstext enthalten ist. Verwenden Sie diesen Code einfach in OnCreate der Aktivität (login_fondo ist das Root-Layout):
quelle
Methode zum Ein- / Ausblenden der Softtastatur
Ich hoffe, sie waren nützlich
quelle
Dies ist die einfachste Lösung für mich (und von mir ausgearbeitet).
Dies ist die Methode zum Ausblenden der Tastatur.
Setzen Sie nun das onclick-Attribut des übergeordneten Layouts der Aktivität
hideKeyboard
entweder in der Entwurfsansicht Ihrer XML-Datei auf die obige Methode oder schreiben Sie den folgenden Code in die Textansicht Ihrer XML-Datei.quelle
Ich habe die Methode verfeinert und den folgenden Code in eine UI-Dienstprogrammklasse eingefügt (vorzugsweise nicht unbedingt), damit von allen Aktivitäts- oder Fragmentklassen auf sie zugegriffen werden kann, um ihren Zweck zu erfüllen.
Sagen Sie dann zum Beispiel, Sie müssen es aus der Aktivität heraus aufrufen, rufen Sie es wie folgt auf;
Beachten
Dies gibt uns die Stammansicht der aktuellen Gruppe (Sie müssen die ID nicht in der Stammansicht festgelegt haben).
Prost :)
quelle
Versuchen Sie stateHidden setzen auf wie Ihre Aktivität
windowSoftInputMode
Werthttp://developer.android.com/reference/android/R.attr.html#windowSoftInputMode
Zum Beispiel für Ihre Aktivität:
quelle
Aktivität
ScreenUtils
quelle
Fügen Sie diesen Code einfach in die Klasse @Overide ein
quelle
Anstatt alle Ansichten zu durchlaufen oder dispatchTouchEvent zu überschreiben.
Warum nicht einfach die onUserInteraction () der Aktivität überschreiben, um sicherzustellen, dass die Tastatur geschlossen wird, wenn der Benutzer außerhalb von EditText tippt.
Funktioniert auch, wenn sich EditText in der scrollView befindet.
quelle
Ich habe dies mit einer kleinen Variante der Lösung von Fernando Camarago zum Laufen gebracht. In meiner onCreate-Methode hänge ich einen einzelnen onTouchListener an die Stammansicht an, sende jedoch die Ansicht und nicht die Aktivität als Argument.
In einer separaten Utils-Klasse ist ...
quelle
Das mag alt sein, aber ich habe es geschafft, indem ich eine benutzerdefinierte Klasse implementiert habe
Die beste Vorgehensweise besteht darin, eine Helper-Klasse zu erstellen, und jeder Container mit relativen / linearen Layouts sollte dies implementieren.
**** Beachten Sie, dass nur der Hauptcontainer diese Klasse implementieren sollte (zur Optimierung) ****
und implementieren Sie es so:
Das Schlüsselwort ist dies für Aktivität. Wenn Sie sich also in einem Fragment befinden, verwenden Sie getActivity ().
--- Daumen hoch, wenn es dir hilft ... --- Prost Ralph ---
quelle
Dies ist eine leicht modifizierte Version von fjes Antwort, die größtenteils perfekt funktioniert hat.
Diese Version verwendet ACTION_DOWN, sodass beim Ausführen einer Bildlaufaktion auch die Tastatur geschlossen wird. Das Ereignis wird auch nicht weitergegeben, es sei denn, Sie klicken auf einen anderen EditText. Dies bedeutet, dass durch Klicken auf eine beliebige Stelle außerhalb Ihres EditText, auch auf eine andere anklickbare, die Tastatur einfach geschlossen wird.
quelle
view
undviewTmp
zugetCurrentFocus()
, sodass sie immer den gleichen Wert haben.Ich habe so gemacht:
Tastaturcode ausblenden :
Erledigt
quelle