webentwicklung-frage-antwort-db.com.de

Tastatur schließen, wenn in Android außerhalb von EditText geklickt wird

Ich habe eine EditText namens myTextview. Ich möchte, dass die Soft-Tastatur angezeigt wird, wenn ich auf die Variable EditText klicke, sie aber dann verwerfen, wenn ich außerhalb der Variablen EditText klicke. Also benutze ich die Methode unten. Die Tastatur wird jedoch nicht verworfen, wenn ich außerhalb der Ansicht klicke (ich klicke auf eine TextView). Wie kann ich diesen Code korrigieren?

myTextview.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
            } else {
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
            }

        }
    });
16
user3093402

Ich habe eine bessere Lösung gefunden:

Überschreiben Sie die dispatchTouchEvent-Methode in Ihrer Aktivität.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    View v = getCurrentFocus();

    if (v != null && 
            (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && 
            v instanceof EditText && 
            !v.getClass().getName().startsWith("Android.webkit.")) {
        int scrcoords[] = new int[2];
        v.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + v.getLeft() - scrcoords[0];
        float y = ev.getRawY() + v.getTop() - scrcoords[1];

        if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())
            hideKeyboard(this);
    }
    return super.dispatchTouchEvent(ev);
}

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

Dies gilt auch, wenn Sie mit Webview arbeiten.

43

Vielleicht etwas einfacher:

Legen Sie einen focusChangedListener für Ihren Bearbeitungstext fest und blenden Sie dann die Tastatur aus, wenn Sie keinen Fokus haben.

yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(!hasFocus){
            hideKeyboard();
        }               
    }
});

private void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
}
15
pat

verwenden Sie folgenden Code.

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

es funktioniert für mich.

3
Ganpat Kaliya

Auf diese Weise verschwindet die Tastatur nur, wenn Sie eine Ansicht berühren, die den Fokus erhält. Ich schlage vor, folgendes zu tun:

Erstellen Sie eine benutzerdefinierte Ansichtsgruppe wie folgt:

public class TouchLayout extends LinearLayout {

    private OnInterceptTouchEventListener mListener;

    public TouchLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if(mListener != null) {
            return mListener.onInterceptTouchEvent(event);
        }
        return super.onInterceptTouchEvent(event);
    }

    public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener listener) {
        mListener = listener;
    }

    public interface OnInterceptTouchEventListener {
        public boolean onInterceptTouchEvent(MotionEvent event);
    }
}

Fügen Sie dann die benutzerdefinierte Ansicht als Stamm Ihres XML-Layouts hinzu:

<com.example.TouchLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/root"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

        <EditText
            Android:id="@+id/text"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content" />

Und in Ihrer Aktivität sollten Sie Folgendes tun:

final TouchLayout root = (TouchLayout) findViewById(R.id.root);
final EditText text = (EditText) findViewById(R.id.text);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

root.setOnInterceptTouchEventListener(new OnInterceptTouchEventListener() {

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        final View v = getCurrentFocus();
        if(v != null && v.equals(text)) {
            final int screenCords[] = new int[2];
            text.getLocationOnScreen(screenCords);
            final Rect textRect = new Rect(screenCords[0], screenCords[1], screenCords[0] + text.getWidth(), screenCords[1] + text.getHeight());
            if(!textRect.contains(event.getRawX(), event.getRawY() {
                imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
                // Optionally you can also do the following:
                text.setCursorVisible(false);
                text.clearFocus(); 
            }
        }
        return false;
    }
};
3
diegocarloslima

Klagegrund: Ich erkenne, dass ich keine Schlagkraft habe, aber bitte nehmen Sie meine Antwort ernst.

Problem: Weiche Tastatur schließen, wenn Sie nicht auf die Tastatur klicken oder Text mit minimalem Code bearbeiten.

Lösung: Externe Bibliothek, bekannt als Buttermesser.

One Line Solution:

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

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

Erläuterung: Binden Sie OnClick Listener an die übergeordnete ID des XML-Layouts der Aktivität, sodass jeder Klick auf das Layout (nicht auf den Bearbeitungstext oder die Tastatur) dies ausführt Code-Schnipsel, das die Tastatur verdeckt.

Beispiel: Wenn Ihre Layoutdatei R.layout.my_layout lautet und Ihre Layout-ID R.id.my_layout_id lautet, sollte Ihr Butterknife-Bind-Aufruf folgendermaßen aussehen:

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

Butterknife Documentation Link: http://jakewharton.github.io/butterknife/

Stecker: Butterknife wird Ihre Android) - Entwicklung revolutionieren. Betrachten Sie es.

2
Charles Woodson

Xamarin Android-Code dafür:

  public override bool DispatchTouchEvent(MotionEvent ev)
    {
        try
        {
            View view = CurrentFocus;
            if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("Android.webkit."))
            {
                int[] Touch = new int[2];
                view.GetLocationOnScreen(Touch);
                float x = ev.RawX + view.Left - Touch[0];
                float y = ev.RawY + view.Top - Touch[1];
                if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom)
                    ((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0);
            }
        }
        catch (System.Exception ex)
        {

        }

        return base.DispatchTouchEvent(ev);
    }
0
G.hakim

Das Berührungsereignis in einer Ansicht beginnt damit, dass ACTION_DOWN von oben an diese Ansichtsansicht-Hierarchie übergeben wird. Überschreiben Sie dispatchTouchEvent, um weitere Aktionen auszuführen. Hier ein Beispiel, um von FrameLayout in kotlin auszugehen:

class TLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null):
        FrameLayout(context, attrs){

    var preDispatchTouchEvent: ((ev: MotionEvent?)->Boolean)? = null

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (preDispatchTouchEvent==null || !preDispatchTouchEvent!!.invoke(ev)) {
            super.dispatchTouchEvent(ev)
        }
        return true
    }

}

Wickeln Sie Ihre EditText und andere relative Views in dieses Layout ein, und legen Sie preDispatchTouchEvent fest, um EditText zu verwerfen, wenn das Ereignis nicht darüber liegt.

Überprüfen Sie diese OS-Frage und offizielle Dokumente , um ein tieferes Verständnis für die Bereitstellung von Touch-Ereignissen zu haben.

0
Lym Zoy

Ich verwende unter Prozess. Es funktioniert perfekt für mich. Fügen Sie in Ihrer Aktivitätsklasse folgende Funktion hinzu.

  override fun dispatchTouchEvent(event: MotionEvent): Boolean {
    if (event.action == MotionEvent.ACTION_DOWN) {
        val v = currentFocus
        if (v is EditText) {
            val outRect = Rect()
            v.getGlobalVisibleRect(outRect)
            if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                Log.d("focus", "touchevent")
                v.clearFocus()
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(v.windowToken, 0)
            }
        }
    }
    return super.dispatchTouchEvent(event)
}

Dann werde ich den Fokusstatus in meinem Fragment überprüfen.

appCompatEditText.onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
                if (!hasFocus) {
                    toast("Focus Off")
                }else {
                    toast("Focus On")
                }
            }

Ich wurde in Fragment eingecheckt. Ich brauchte den Fokusstatus für meine Aufgabe Anforderung. Focus Out Ich brauchte eine Aufgabe.

0
Shohel Rana