2010-08-06 60 views
89

我在我的視圖中有一個EditText小部件。當用戶選擇EditText小部件時,我會顯示一些說明並出現軟鍵盤。檢測用戶何時解除軟鍵盤

我使用一個OnEditorActionListener來檢測用戶何時完成文本輸入,然後關閉鍵盤,隱藏說明並執行一些操作。

我的問題是當用戶通過按BACK鍵關閉鍵盤。操作系統關閉了鍵盤,但我的指令(我需要隱藏)仍然可見。

我試過重寫OnKeyDown,但是當BACK按鈕用於關閉鍵盤時,這似乎不會被調用。

我試過在EditText小部件上設置一個OnKeyListener,但似乎並沒有被調用。

如何檢測軟鍵盤何時被解除?

回答

144

我知道一個辦法做到這一點。子類中的EditText和實施:

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

下面是關於如何使用您的自定義視圖的鏈接(當你繼承的EditText的): http://developer.android.com/guide/topics/ui/custom-components.html

+1

我正在從Android的報道正確的使用硬件鍵盤的用戶會以某種方式干擾按鍵。我目前沒有任何其他信息。 – esilver 2011-11-14 21:57:58

+0

我一直在尋找幾種解決方案,這是迄今爲止最好的! – Friesgaard 2014-03-20 22:01:22

+9

等待等待,我只是第三次看這個 - 不應該超級調用onKeyPreIme嗎?還是有一個特別的原因,它不是這樣嗎? – Erhannis 2014-07-03 00:55:00

110

周杰倫,你的解決方案是好的!

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

妙解,周杰倫,+1:謝謝:)

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抱歉,但是如何爲EditText創建事件處理程序? – Manolis 2014-08-26 15:02:56

+1

+1謝謝你這個非常有用和聰明的答案。你救了我一天的男人。再次感謝你;) – Sajmon 2014-09-30 17:46:39

+0

我們想要檢測'KeyEvent.ACTION_UP'的任何特殊原因? – 2015-06-18 08:54:10

17

我通過調用super.onKeyPreIme()由周杰倫的解決方案略有變化!

4

只需創建一個擴展EDITTEXT類和使用的EditText在你的代碼, 你應該只覆蓋在定製的EditText如下方法:

@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

Is there一種檢測鍵盤何時打開的方法? – powder366 2016-05-07 11:30:35

13

這裏是我的自定義的EditText檢測鍵盤是否被顯示或不是

/** 
* 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

下面是關鍵聽衆的解決方案。 我不知道爲什麼這個工作,但OnKeyListener的作品,如果你只是在你的自定義EditText上重寫onKeyPreIme。

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的答案,但轉化爲科特林:

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