2010-08-06 20 views
89

Ich habe ein EditText Widget in meiner Sicht. Wenn der Benutzer das EditText-Widget auswählt, zeige ich einige Anweisungen an und die Soft-Tastatur erscheint.Erkennen, wenn der Benutzer die Soft-Tastatur entlassen hat

Ich verwende einen OnEditorActionListener, um zu erkennen, wann der Benutzer die Texteingabe abgeschlossen hat und ich die Tastatur verlasse, die Anweisungen verberge und etwas unternehme.

Mein Problem ist, wenn der Benutzer die Tastatur durch Drücken der Taste BACK entlässt. Das Betriebssystem entlässt die Tastatur, aber meine Anweisungen (die ich verstecken muss) sind immer noch sichtbar.

Ich habe versucht, OnKeyDown zu überschreiben, aber das scheint nicht aufgerufen werden, wenn die BACK-Taste verwendet wird, um die Tastatur zu schließen.

Ich habe versucht, einen OnKeyListener auf dem Widget EditText, aber das scheint auch nicht aufgerufen werden.

Wie kann ich erkennen, wenn die Soft-Tastatur geschlossen wird?

Antwort

144

Ich kenne einen Weg, dies zu tun. Subklassen die EditText und implementieren:

@Override 
public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
    // Do your thing. 
    return true; // So it is not propagated. 
    } 
    return super.dispatchKeyEvent(event); 
} 

Hier ist ein Link, wie Sie Ihre benutzerdefinierten Ansichten verwenden (wenn Sie eine Unterklasse EditText): http://developer.android.com/guide/topics/ui/custom-components.html

+1

ich Berichte von Android bin immer Benutzer mit Hardware-Tastaturen, die dies tun, stört Tastatureingaben irgendwie. Ich habe derzeit keine zusätzlichen Informationen. – esilver

+0

Ich habe mehrere Lösungen gesucht, das ist bei weitem das beste! – Friesgaard

+9

Warte warten, ich habe mir das ein drittes Mal angeschaut - sollte nicht der Superruf zu "onKeyPreIme" sein? Oder gibt es einen besonderen Grund dafür, dass es nicht so ist? – Erhannis

110

Jay, Ihre Lösung ist gut! Dank :)

public class EditTextBackEvent extends EditText { 

    private EditTextImeBackListener mOnImeBack; 

    public EditTextBackEvent(Context context) { 
     super(context); 
    } 

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

    public EditTextBackEvent(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
     if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && 
      event.getAction() == KeyEvent.ACTION_UP) { 
      if (mOnImeBack != null) 
       mOnImeBack.onImeBack(this, this.getText().toString()); 
     } 
     return super.dispatchKeyEvent(event); 
    } 

    public void setOnEditTextImeBackListener(EditTextImeBackListener listener) { 
     mOnImeBack = listener; 
    } 

} 

public interface EditTextImeBackListener { 
    public abstract void onImeBack(EditTextBackEvent ctrl, String text); 
} 
+0

@oliver_sdg Entschuldigung für die Neuling Frage, aber wie erstelle ich den Event-Handler für den EditText? – Manolis

+1

+1 Vielen Dank für diese sehr nützliche und intelligente Antwort. Du hast meinen Tag-Mann gerettet. Vielen Dank nochmals;) – Sajmon

+0

Gibt es einen besonderen Grund, warum wir 'KeyEvent.ACTION_UP' ebenfalls erkennen wollen? –

17

Ich habe eine leichte Veränderung auf Jay-Lösung von super.onKeyPreIme() aufgerufen:

_e = new EditText(inflater.getContext()) { 
@Override 
public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){ 
      cancelTextInput(); 
     } 
     return super.onKeyPreIme(keyCode, event); 
    } 
}; 

Wunderbare Lösung, Jay, +1!

4

einfach eine Klasse erstellen, die EditText erstreckt und dass EditText in Ihrem Code verwenden, Sie sollten nur die folgende Methode in der benutzerdefinierten EditText außer Kraft setzen:

@Override 
public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
if (keyCode == KeyEvent.KEYCODE_BACK) { 

    //Here it catch all back keys 
    //Now you can do what you want. 

} else if (keyCode == KeyEvent.KEYCODE_MENU) { 
    // Eat the event 
    return true; 
} 
return false;} 
+0

Ist da eine Möglichkeit zu erkennen, wenn die Tastatur öffnet? – powder366

13

Hier ist meine individuelle EditText zu erkennen, ob Tastatur zeigt, oder nicht

/** 
* Created by TheFinestArtist on 9/24/15. 
*/ 
public class KeyboardEditText extends EditText { 

    public KeyboardEditText(Context context) { 
     super(context); 
    } 

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

    public KeyboardEditText(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 
     super.onFocusChanged(focused, direction, previouslyFocusedRect); 
     if (listener != null) 
      listener.onStateChanged(this, true); 
    } 

    @Override 
    public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) { 
     if (event.getKeyCode() == KeyEvent.KEYCODE_BACK 
       && event.getAction() == KeyEvent.ACTION_UP) { 
      if (listener != null) 
       listener.onStateChanged(this, false); 
     } 
     return super.onKeyPreIme(keyCode, event); 
    } 

    /** 
    * Keyboard Listener 
    */ 
    KeyboardListener listener; 

    public void setOnKeyboardListener(KeyboardListener listener) { 
     this.listener = listener; 
    } 

    public interface KeyboardListener { 
     void onStateChanged(KeyboardEditText keyboardEditText, boolean showing); 
    } 
} 
1

Hier ist eine Lösung mit dem Schlüsselhörer. Ich habe keine Ahnung, warum das funktioniert, aber OnKeyListener funktioniert, wenn Sie onKeyPreIme auf Ihrem benutzerdefinierten EditText einfach nur überschreiben.

SomeClass.java

customEditText.setOnKeyListener((v, keyCode, event) -> { 
      if(event.getAction() == KeyEvent.ACTION_DOWN) { 
       switch (keyCode) { 
        case KeyEvent.KEYCODE_BACK: 
         getPresenter().onBackPressed(); 
         break; 
       } 
      } 
      return false; 
     }); 

CustomEditText.java

@Override 
    public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
     return super.dispatchKeyEvent(event); 
    } 
0

@ olivier_sdg Antwort verwenden, aber auf Kotlin umgewandelt:

class KeyboardEditText : EditText { 

    private var mOnImeBack: EditTextImeBackListener? = null 

    constructor(context: Context) : super(context) 
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 

    override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean { 
     if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) { 
      if (mOnImeBack != null) 
       mOnImeBack!!.onImeBack(this, this.text.toString()) 
     } 
     return super.dispatchKeyEvent(event) 
    } 

    fun setOnEditTextImeBackListener(listener: EditTextImeBackListener) { 
     mOnImeBack = listener 
    } 

} 

interface EditTextImeBackListener { 
    fun onImeBack(ctrl: KeyboardEditText, text: String) 
} 
Verwandte Themen