Frage

Ok jeder weiß, dass eine Tastatur verstecken Sie implementieren müssen:

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

Aber die große Sache hier ist, wie die Tastatur auszublenden, wenn der Benutzer berührt oder wählt an jedem anderen Ort, der kein EditText oder das Softkeyboard ist?

Ich habe versucht, die onTouchEvent() auf meine Eltern Activity zu verwenden, aber das funktioniert nur, wenn der Benutzer berührt außerhalb jeder anderen Ansicht und es gibt keine Scroll.

Ich habe versucht, eine Verbindung zu implementieren, klicken Sie auf, Fokus Hörer ohne Erfolg.

Ich habe sogar versucht, meine eigene Scroll abfangen Touch-Ereignisse zu implementieren, aber ich kann nur die Koordinaten des Ereignisses erhalten und nicht der Ansicht geklickt haben.

Gibt es eine standardisierte Möglichkeit, dies zu tun ?? in iPhone war es wirklich einfach.

War es hilfreich?

Lösung

Das folgende Snippet einfach versteckt die Tastatur:

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

Sie können dies in einer Utility-Klasse setzen, oder wenn Sie es innerhalb einer Aktivität definieren, vermeiden Sie den Aktivitätsparameter oder Anruf hideSoftKeyboard(this).

Der schwierigste Teil ist, wenn es zu nennen. Sie können eine Methode schreiben, dass iteriert durch jedes View in Ihrer Tätigkeit, und überprüfen, ob es sich um eine instanceof EditText ist, wenn es nicht eine setOnTouchListener auf diese Komponente registrieren und alles wird an Ort und Stelle fallen. Falls Sie sich fragen, wie das zu tun, ist es in der Tat ganz einfach. Hier ist, was Sie tun, Sie eine rekursive Methode, wie die folgende schreiben, in der Tat können Sie diese verwenden, alles zu tun, wie Setup benutzerdefinierte Schriftarten etc ... 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 einfach diese Methode, nachdem Sie in Ihrer Tätigkeit setContentView. Falls Sie sich fragen, was Parameter Sie würde passieren, ist es der id des übergeordneten Containers. Weisen Sie eine id zu Ihrem übergeordneten Container wie

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

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

Wenn Sie diese effektiv nutzen möchten, können Sie eine erweiterte Activity und setzen diese Methode in erstellen und machen alle anderen Aktivitäten in der Anwendung dieser Tätigkeit erweitern und seine setupUI() im onCreate() Methode aufrufen.

Hope es hilft.

Wenn Sie mehr als 1-Aktivität verwenden definieren gemeinsame ID Eltern 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 diese Klasse statt `` Activityin your program

Andere Tipps

Sie können dies erreichen, indem Sie die folgenden Schritte ausführen:

  1. Machen Sie die übergeordnete Ansicht (Inhalt Ansicht Ihrer Aktivität) anklickbar und fokussierbar durch folgende Attribute hinzugefügt

        android:clickable="true" 
        android:focusableInTouchMode="true" 
    
  2. Implementieren eines hideKeyboard () Methode

        public void hideKeyboard(View view) {
            InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    
  3. Schließlich setzen die onFocusChangeListener Ihrer EditText.

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

Wie bereits unten in einen der Kommentare aus, dies möglicherweise nicht, wenn die übergeordnete Ansicht eine Scrollview ist. Für einen solchen Fall kann die klickbare und focusableInTouchMode auf der Ansicht direkt unter dem Scrollview hinzugefügt werden.

ich die akzeptierte Antwort finden ein wenig kompliziert.

Hier ist meine Lösung. Fügen Sie einen OnTouchListener zu Ihrem Haupt-Layout, das heißt:.

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

und setzen Sie den folgenden Code in dem OnTouch Verfahren.

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

Auf diese Weise müssen Sie nicht zu iterieren allen Ansichten.

bekam ich noch eine Lösung, um die Tastatur auszublenden durch:

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

Hier HIDE_IMPLICIT_ONLY an der Position der showFlag und 0 an der Position des hiddenFlag passieren. Es wird mit Nachdruck nahe der Soft-Tastatur.

Just Überschreibung Code unten in 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);
}

Nun schaffe ich das Problem zu lösen, etwas, ich die dispatchTouchEvent overrode auf meine Tätigkeit, da ich bin mit der im Anschluss an die Tastatur auszublenden.

 /**
 * Called to process touch screen events. 
 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    switch (ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchDownTime = SystemClock.elapsedRealtime();
            break;

        case MotionEvent.ACTION_UP:
            //to avoid drag events
            if (SystemClock.elapsedRealtime() - touchDownTime <= 150){  

                EditText[] textFields = this.getFields();
                if(textFields != null && textFields.length > 0){

                    boolean clickIsOutsideEditTexts = true;

                    for(EditText field : textFields){
                        if(isPointInsideView(ev.getRawX(), ev.getRawY(), field)){
                            clickIsOutsideEditTexts = false;
                            break;
                        }
                    }

                    if(clickIsOutsideEditTexts){
                        this.hideSoftKeyboard();
                    }               
                } else {
                    this.hideSoftKeyboard();
                }
            }
            break;
    }

    return super.dispatchTouchEvent(ev);
}

EDIT: Die getFields () Methode ist nur ein Verfahren, welches Returns ein Array mit den Textfeldern in der Ansicht. die Schaffung diese Anordnung auf jeder Berührung zu vermeiden, habe ich ein statisches Array sFields genannt, die an dem getFields () Methode zurückgegeben wird. Dieses Array wird auf der onStart () initialisiert Methoden wie:

sFields = new EditText[] {mUserField, mPasswordField};


Es ist nicht perfekt ist, wird die Drag-Ereignis Zeit auf Heuristiken nur auf Basis so manchmal verstecken tut, wenn lange clics Durchführung und ich beenden auch durch ein Verfahren zu schaffen alle die editTexts pro Ansicht zu erhalten; sonst würde die Tastatur ein- und ausgeblendet, wenn andere EditText klicken.

Still, saubere und kürzere Lösungen sind willkommen

Verwenden Sie OnFocusChangeListener .

Zum Beispiel:

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

Aktualisieren : Sie können auch onTouchEvent() in Ihrer Aktivität außer Kraft setzen und Koordinaten der Berührung überprüfen. Wenn Koordinaten außerhalb von EditText sind, dann verstecken Sie die Tastatur.

I dispatchTouchEvent in Aktivität umgesetzt, dies zu tun:

private EditText mEditText;
private Rect mRect = new Rect();
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    int[] location = new int[2];
    mEditText.getLocationOnScreen(location);
    mRect.left = location[0];
    mRect.top = location[1];
    mRect.right = location[0] + mEditText.getWidth();
    mRect.bottom = location[1] + mEditText.getHeight();

    int x = (int) ev.getX();
    int y = (int) ev.getY();

    if (action == MotionEvent.ACTION_DOWN && !mRect.contains(x, y)) {
        InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        input.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

und Getestet habe ich es funktioniert perfekt!

Ignorieren public boolean dispatchTouchEvent (Motion Ereignis) in jeder Aktivität (oder verlängert Klasse von Aktivität)

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    View view = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

    if (view instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];

        if (event.getAction() == MotionEvent.ACTION_UP 
 && (x < w.getLeft() || x >= w.getRight() 
 || y < w.getTop() || y > w.getBottom()) ) { 
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
        }
    }
 return ret;
}

Und das ist alles, was Sie tun müssen,

Ein Kotlin & Material Design Art und Weise mit TextInputEditText (dieser Ansatz ist auch kompatibel mit EditTextView ) ...

1.Make die übergeordnete Ansicht (Inhalt Ansicht Ihrer Aktivität / Fragment) anklickbar und fokussierbar durch folgende Attribute hinzugefügt

android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"

2.Create eine Erweiterung für alle Ansicht (in einer ViewExtension.kt Datei zum Beispiel):

fun View.hideKeyboard(){
    val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.hideSoftInputFromWindow(this.windowToken, 0)
}

3.Create ein BaseTextInputEditText dass erben von TextInputEditText. Implementieren Sie die Methode zu verstecken Tastatur onFocusChanged, wenn die Ansicht nicht fokussiert:

class BaseTextInputEditText(context: Context?, attrs: AttributeSet?) : TextInputEditText(context, attrs){
    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        if (!focused) this.hideKeyboard()
    }
}

4.Just rufen Sie Ihre neue benutzerdefinierte Ansicht in Ihrer XML:

<android.support.design.widget.TextInputLayout
        android:id="@+id/textInputLayout"
        ...>

        <com.your_package.BaseTextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            ... />

    </android.support.design.widget.TextInputLayout> 

Das ist alles. Keine Notwendigkeit, Ihre Controller zu ändern (Fragment oder Aktivität) diesen repetitiven Fall zu behandeln.

Ich bin mir bewusst, dass dieser Thread schon recht alt ist, die richtige Antwort scheint gültig und es gibt eine Menge von Arbeitslösungen gibt, aber ich denke, der Ansatz damit, brüllen könnte einen zusätzlichen Vorteil in Bezug auf Effizienz und Eleganz hat.

ich brauche dieses Verhalten für alle meine Aktivitäten, so dass ich eine Klasse erstellt CustomActivity aus der Klasse erben Aktivität und "süchtig" die dispatchTouchEvent Funktion. Es gibt im Wesentlichen zwei Bedingungen zu kümmern:

  1. Wenn der Fokus unverändert und jemand außerhalb des aktuellen Eingabefeld tippen, dann schließen Sie das IME
  2. Wenn der Fokus geändert hat und das nächste fokussierte Element ist keine Instanz von jeder Art von einem Eingabefeld, dann schließen Sie das IME

Das ist mein Ergebnis:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if(ev.getAction() == MotionEvent.ACTION_UP) {
        final View view = getCurrentFocus();

        if(view != null) {
            final boolean consumed = super.dispatchTouchEvent(ev);

            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view)) {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y)) {
                    return consumed;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText) {
                return consumed;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return consumed;
        }
    }       

    return super.dispatchTouchEvent(ev);
}

Side Hinweis: Zusätzlich ordne ich diese Attribute in die Wurzel Ansicht es möglich, klare Fokussierung auf jedem Eingabefeld machen und Eingang verhindert Felder Fokus auf Aktivität Start gewinnen (was den Inhalt Ansicht des „Fokus catcher“):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final View view = findViewById(R.id.content);

    view.setFocusable(true);
    view.setFocusableInTouchMode(true);
}

ich die Lösung von Andre Luis IM I geändert, um diese eine erreicht:

Ich habe eine Dienstprogramm Methode, um die Soft-Tastatur auf die gleiche Weise Andre Luiz IM tat zu verbergen:

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

Aber anstatt eine OnTouchListener für jede Ansicht des Register, das eine schlechte Leistung geben, registrierte ich die OnTouchListener nur für die Stammansicht. Da die Veranstaltung Blasen, bis es verbraucht ist (EditText ist eine der Ansichten, dass es standardmäßig verbraucht), wenn es in die Wurzel Ansicht kommt, ist es, weil es nicht verbraucht wurde, so dass ich die Soft-Tastatur schließen.

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

mochte ich den Ansatz des Aufrufs dispatchTouchEvent von htafoya gemacht, aber:

  • Ich habe nicht den Timer Teil verstehen (weiß nicht, warum die Ausfallzeiten Messung notwendig sein sollte?)
  • mag ich nicht registrieren / unregister alle EditTexts mit jeder Ansicht Wechsel (könnte ziemlich viel viewchanges und edittexts in komplexen Hierarchien)

Also, ich habe diese etwas einfachere Lösung:

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    // all touch events close the keyboard before they are processed except EditText instances.
    // if focus is an EditText we need to check, if the touchevent was inside the focus editTexts
    final View currentFocus = getCurrentFocus();
    if (!(currentFocus instanceof EditText) || !isTouchInsideView(ev, currentFocus)) {
        ((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE))
            .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
    return super.dispatchTouchEvent(ev);
}

/**
 * determine if the given motionevent is inside the given view.
 * 
 * @param ev
 *            the given view
 * @param currentFocus
 *            the motion event.
 * @return if the given motionevent is inside the given view
 */
private boolean isTouchInsideView(final MotionEvent ev, final View currentFocus) {
    final int[] loc = new int[2];
    currentFocus.getLocationOnScreen(loc);
    return ev.getRawX() > loc[0] && ev.getRawY() > loc[1] && ev.getRawX() < (loc[0] + currentFocus.getWidth())
        && ev.getRawY() < (loc[1] + currentFocus.getHeight());
}

Es gibt einen Nachteil:

Der Wechsel von einem auf einen anderen EditText EditText macht die Tastatur auszublenden und wieder aufführen -. In meinem Fall ist es erwünscht, dass Art und Weise, denn es zeigt, dass Sie zwischen zwei Eingangskomponenten geschaltet

Plädoyer: Ich erkenne ich keinen Einfluss haben, aber bitte ernst meine Antwort nehmen.

Problem:. Soft-Tastatur Entlassen, wenn von der Tastatur oder Bearbeiten von Text mit minimalem Code Klick entfernt

. Lösung: Externe Bibliothek bekannt als butter

One Line Lösung:

@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }

lesbare Lösung:

@OnClick(R.id.activity_signup_layout) 
public void closeKeyboard() {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

Erklärung: Bind OnClick Listener auf die ID-XML-Layout-Eltern-Aktivität, so dass jeder Klick auf dem Layout (nicht auf dem Bearbeiten von Text oder Tastatur) wird diesen Code-Snippet ausgeführt werden, die die Tastatur verstecken .

Beispiel: Wenn Ihre Layout-Datei R.layout.my_layout ist und Ihre Layout-ID ist R.id.my_layout_id, dann bindet butter Aufruf soll wie folgt aussehen:

(@OnClick(R.id.my_layout_id) 
public void yourMethod {
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

butter Dokumentation Verweis: http://jakewharton.github.io/butterknife /

Stecker: butter wird Ihr Android-Entwicklung revolutionieren. Betrachten Sie es.

Hinweis: Das gleiche Ergebnis kann ohne den Einsatz von externer Bibliothek Buttermesser erreicht werden. Nur einen OnClickListener auf das übergeordnete Layout gesetzt, wie oben beschrieben.

Hier ist eine andere Variante FJE Antwort, dass Adressen die Probleme von sosite erhöht.

Die Idee dabei ist sowohl die nach unten und den Maßnahmen in der Tätigkeit der dispatchTouchEvent Methode zu behandeln. Auf der anderen Aktion machen wir Kenntnis von der momentan fokussierten Ansicht (falls vorhanden) und ob die Berührung im Innern war es, für später diese beiden Bits an Informationen zu speichern.

Auf der Aktion, wir erste Dispatch, eine andere Ansicht, damit potenziell Fokus nehmen. Wenn danach, zur Zeit der fokussierte Sicht der ursprünglich fokussierte Sicht ist, und die nach unten berühren innerhalb dieser Ansicht war, dann verlassen wir die Tastatur geöffnet ist.

Wenn die aktuell fokussierte Sicht ist anders als die ursprünglich Blick fokussiert und es ist ein EditText, dann lassen wir auch die Tastatur geöffnet ist.

Ansonsten schließen wir es.

Also, um es zusammenzufassen, das funktioniert wie folgt:

  • , wenn sie innerhalb eines aktuell fokussiert EditText berühren, öffnen Sie die Tastatur Aufenthalte
  • , wenn sie von einem fokussierten EditText auf einem anderen EditText bewegen, die Tastatur bleibt geöffnet (nicht in der Nähe / wieder öffnen)
  • wenn berühren überall außerhalb eines zur Zeit konzentriert EditText, die nicht eine andere EditText ist, die Tastatur schließt
  • wenn sie in einem EditText langes Drücken der kontextuellen Aktionsleiste zu bringen (mit dem Cut / Copy / Paste-Tasten), die Tastatur bleibt geöffnet, auch wenn die UP Aktion außerhalb des fokussierten EditText nahm (was zu machen nach unten verschoben Raum für die CAB). Beachten Sie jedoch, dass, wenn Sie auf eine Schaltfläche in der CAB tippen, wird die Tastatur schließen. Das mag sein oder auch nicht wünschenswert; wenn Sie Ausschneiden / Kopieren von einem Feld wollen und zum anderen einfügen, wäre es. Wenn Sie die gleiche EditText einfügen zurück in wollen, wäre es nicht sein.
  • , wenn der fokussierte EditText am unteren Rand des Bildschirms, und Sie lange Sie auf einen Text um es auszuwählen, hält die EditText Fokus und damit die Tastatur öffnet sich wie Sie wollen, weil wir die „touch tun ist, innerhalb Ansicht Grenzen“Überprüfung der nach unten Aktion, nicht die Aktion.

    private View focusedViewOnActionDown;
    private boolean touchWasInsideFocusedView;
    
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                focusedViewOnActionDown = getCurrentFocus();
                if (focusedViewOnActionDown != null) {
                    final Rect rect = new Rect();
                    final int[] coordinates = new int[2];
    
                    focusedViewOnActionDown.getLocationOnScreen(coordinates);
    
                    rect.set(coordinates[0], coordinates[1],
                            coordinates[0] + focusedViewOnActionDown.getWidth(),
                            coordinates[1] + focusedViewOnActionDown.getHeight());
    
                    final int x = (int) ev.getX();
                    final int y = (int) ev.getY();
    
                    touchWasInsideFocusedView = rect.contains(x, y);
                }
                break;
    
            case MotionEvent.ACTION_UP:
    
                if (focusedViewOnActionDown != null) {
                    // dispatch to allow new view to (potentially) take focus
                    final boolean consumed = super.dispatchTouchEvent(ev);
    
                    final View currentFocus = getCurrentFocus();
    
                    // if the focus is still on the original view and the touch was inside that view,
                    // leave the keyboard open.  Otherwise, if the focus is now on another view and that view
                    // is an EditText, also leave the keyboard open.
                    if (currentFocus.equals(focusedViewOnActionDown)) {
                        if (touchWasInsideFocusedView) {
                            return consumed;
                        }
                    } else if (currentFocus instanceof EditText) {
                        return consumed;
                    }
    
                    // the touch was outside the originally focused view and not inside another EditText,
                    // so close the keyboard
                    InputMethodManager inputMethodManager =
                            (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMethodManager.hideSoftInputFromWindow(
                        focusedViewOnActionDown.getWindowToken(), 0);
                    focusedViewOnActionDown.clearFocus();
    
                    return consumed;
                }
                break;
        }
    
        return super.dispatchTouchEvent(ev);
    }
    

es zu einfach, nur machen Sie Ihr letztes Layout eine fokussierbare klickbare durch diesen Code:

android:id="@+id/loginParentLayout"
android:clickable="true"
android:focusableInTouchMode="true"

und schreiben dann ein Verfahren und eine OnClickListner für das Layout, so dass, wenn das oberste Layout jeder berührt wird, wo es eine Methode aufrufen wird, in dem Sie Code schreiben, wird Tastatur zu entlassen. Folgendes ist der Code für beide; // Sie haben, dies zu schreiben in OnCreate ()

 yourLayout.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View view) {
                    hideKeyboard(view);
                }
            });

Methode von listner genannt: -

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

Ich finde die akzeptierte Antwort auf diese einfache Anforderung komplexe Bit. Hier ist, was für mich gearbeitet, ohne Panne.

findViewById(R.id.mainLayout).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            return false;
        }
    });

Verfahren zur Ein- / Ausblenden Soft-Tastatur

InputMethodManager inputMethodManager = (InputMethodManager) currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (isShow) {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        } else {
            inputMethodManager.showSoftInput(currentActivity.getCurrentFocus(), InputMethodManager.SHOW_FORCED);    
        }

    } else {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
        } else {
            inputMethodManager.hideSoftInputFromInputMethod(currentActivity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);    
        }

    }

Ich hoffe, dass sie nützlich gewesen,

Es gibt einen einfacheren Ansatz, basierend auf dem iPhone gleiches Problem. Einfach das Layout auf Touch-Veranstaltung Hintergrund überschreiben, in dem der Text bearbeiten enthalten ist. Verwenden Sie einfach diesen Code in der OnCreate Aktivität (login_fondo ist die Wurzel-Layout):

    final LinearLayout llLogin = (LinearLayout)findViewById(R.id.login_fondo);
    llLogin.setOnTouchListener(
            new OnTouchListener()
            {
                @Override
                public boolean onTouch(View view, MotionEvent ev) {
                    InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
                            android.content.Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mActivity.getCurrentFocus().getWindowToken(), 0);
                    return false;
                }
            });

Ich habe die Methode verfeinert, setzen Sie den folgenden Code in einigen UI Utility-Klasse (vorzugsweise nicht notwendigerweise), so dass sie von allen Ihre Aktivität oder Fragment Klassen zugegriffen werden kann, um ihren Zweck zu dienen.

public static void serachAndHideSoftKeybordFromView(View view, final Activity act) {
    if(!(view instanceof EditText)) {
        view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(act);
                return false;
            }
        });
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View nextViewInHierarchy = ((ViewGroup) view).getChildAt(i);
            serachAndHideSoftKeybordFromView(nextViewInHierarchy, act);
        }
    }
}
public static void hideSoftKeyboard (Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

sagen dann zum Beispiel müssen Sie es nennen von Aktivität, nennen Sie es wie folgt:

UIutils.serachAndHideSoftKeybordFromView(findViewById(android.R.id.content), YourActivityName.this);

Hinweis

findViewById (android.R.id.content)

Das gibt uns die Stammansicht der aktuellen Gruppe (Sie nicht die ID auf Root-Ansicht eingestellt haben müssen).

Prost:)

Versuchen stateHidden auf als Ihre Aktivität windowSoftInputMode Wert zu setzen

http://developer.android.com/reference/android/ R.attr.html # windowSoftInputMode

Zum Beispiel für Ihre Aktivität:

this.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

Aktivität

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
     ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
     return super.dispatchTouchEvent(ev);
 }

ScreenUtils

 public static void hideKeyboard(Context context, IBinder windowToken) {
     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
 }

Fügen Sie einfach diesen Code in der Klasse @Overide

public boolean dispatchTouchEvent(MotionEvent ev) {
    View view = getCurrentFocus();
    if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        view.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + view.getLeft() - scrcoords[0];
        float y = ev.getRawY() + view.getTop() - scrcoords[1];
        if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
            ((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
    }
    return super.dispatchTouchEvent(ev);
}

In Kotlin, können wir folgendes tun. Keine Notwendigkeit, Iterierte alle Ansichten. Es wird auch für Fragmente arbeiten.

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

Dieses alte sein kann, aber ich habe diese Arbeit durch eine benutzerdefinierte Klasse implenting

public class DismissKeyboardListener implements OnClickListener {

    Activity mAct;

    public DismissKeyboardListener(Activity act) {
        this.mAct = act;
    }

    @Override
    public void onClick(View v) {
        if ( v instanceof ViewGroup ) {
            hideSoftKeyboard( this.mAct );
        }
    }       
}

public void hideSoftKeyboard(Activity activity) {
        InputMethodManager imm = (InputMethodManager)
        getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}

die beste Praxis hier ist eine Hilfsklasse und jeden Behälter relativ zu erstellen / Linear Layouts sollen dies umzusetzen.

**** Beachten Sie nur die Haupt Container sollte diese Klasse implementieren (Zur Optimierung) ****

und setzen es wie folgt aus:

Parent.setOnClickListener( new DismissKeyboardListener(this) ); 

das Schlüsselwort ist dies für Aktivität. Wenn Sie also auf Fragmente sind verwenden Sie wie getActivity ();

--- Daumen nach oben, wenn es Ihnen helfen, ... --- prost Ralph ---

Dies ist eine leicht modifizierte Version der Antwort des FJE der perfekt meist gearbeitet.

Diese Version verwendet ACTION_DOWN so eine Scroll-Aktion ausführt schließt auch die Tastatur. Es ist propagiert auch nicht das Ereignis, wenn Sie auf einem anderen EditText klicken. Dies bedeutet, dass überall außerhalb Ihres EditText, auch auf einem anderen klickbare klicken, schließt einfach die Tastatur.

@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
    if(ev.getAction() == MotionEvent.ACTION_DOWN)
    {
        final View view = getCurrentFocus();

        if(view != null)
        {
            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view))
            {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y))
                {
                    super.dispatchTouchEvent(ev);
                    return true;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText)
            {
                super.dispatchTouchEvent(ev);
                return true;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

Ich habe diese Art und Weise geschehen:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
   View view = getCurrentFocus();
   if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
            int scrcoords[] = new int[2];
            view.getLocationOnScreen(scrcoords);
            float x = ev.getRawX() + view.getLeft() - scrcoords[0];
            float y = ev.getRawY() + view.getTop() - scrcoords[1];
            if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
                hideKeyboard(this);
        }
    return super.dispatchTouchEvent(ev);
}

ausblenden Tastaturcode :

public static void hideKeyboard(Activity act) {
    if(act!=null)
      ((InputMethodManager)act.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((act.getWindow().getDecorView().getApplicationWindowToken()), 0);
  }

Fertig

Um dieses Problem zu lösen, was Sie tun müssen, ist die erste Gebrauch setOnFocusChangeListener davon EditText

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    Log.d("focus", "focus loosed");
                    // Do whatever you want here
                } else {
                    Log.d("focus", "focused");
                }
            }
        });

und dann, was Sie tun müssen, ist überschreiben dispatchTouchEvent in der Aktivität, die enthält, dass EditText ein code

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View v = getCurrentFocus();
        if ( v instanceof EditText) {
            Rect outRect = new Rect();
            v.getGlobalVisibleRect(outRect);
            if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                Log.d("focus", "touchevent");
                v.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

Jetzt wird passieren, was ist, wenn ein Benutzer außerhalb klicken Sie dann auf zunächst diese dispatchTouchEvent wird aufgerufen, die dann den Fokus von der EditExt klar wird nun Ihre OnFocusChangeListener wird aufgerufen, dass der Fokus jetzt hier geändert wurde, können Sie etwas tun, was Sie tun wollte hoffe, es funktioniert

@Override
    public boolean onTouchEvent(MotionEvent event) {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.
                INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        return true;
    }

Nun, können Sie diesen Code verwenden, Verwenden Sie Ihr Haupt Layout-Id anstelle von "mainRelativeLayout"

//hide Soft keyboard on click outside  the input text
    findViewById(R.id.mainRelativeLayout).setOnClickListener(new 
View.OnClickListener() {
        @Override
        public void onClick(View v) {
            InputMethodManager im = (InputMethodManager) 
getSystemService(INPUT_METHOD_SERVICE);
            im.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 
0);
        }

    });
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top