Android 检测用户何时关闭软键盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3425932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting when user has dismissed the soft keyboard
提问by deSelby
I have an EditText widget in my view. When the user selects the EditText widget, I display some instructions and the soft keyboard appears.
我的视图中有一个 EditText 小部件。当用户选择 EditText 小部件时,我会显示一些说明并出现软键盘。
I use an OnEditorActionListener to detect when the user has completed text entry and I dismiss the keyboard, hide the instructions and perform some action.
我使用 OnEditorActionListener 来检测用户何时完成文本输入,然后关闭键盘、隐藏指令并执行一些操作。
My problem is when the user dismisses the keyboard by pressing the BACK key. The OS dismisses the keyboard, but my instructions (which I need to hide) are still visible.
我的问题是当用户通过按 BACK 键关闭键盘时。操作系统关闭键盘,但我的指令(我需要隐藏)仍然可见。
I've tried overriding OnKeyDown, but that doesn't seem to get called when the BACK button is used to dismiss the keyboard.
我试过覆盖 OnKeyDown,但是当使用 BACK 按钮关闭键盘时,它似乎没有被调用。
I've tried setting an OnKeyListener on the EditText widget, but that doesn't seem to get called either.
我试过在 EditText 小部件上设置 OnKeyListener ,但似乎也没有被调用。
How can I detect when the soft keyboard is being dismissed?
如何检测软键盘何时被关闭?
回答by Jay
I know a way to do this. Subclass the EditText and implement:
我知道一种方法来做到这一点。子类化 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);
}
Here is a link on how to use your custom views (for when you subclass EditText): http://developer.android.com/guide/topics/ui/custom-components.html
以下是有关如何使用自定义视图的链接(用于子类 EditText 时):http: //developer.android.com/guide/topics/ui/custom-components.html
回答by olivier_sdg
Jay, your solution is good ! thanks :)
杰伊,你的解决方案很好!谢谢 :)
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);
}
回答by Steelight
I made a slight change on Jay's solution by calling super.onKeyPreIme():
我通过调用 super.onKeyPreIme() 对 Jay 的解决方案进行了轻微更改:
_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);
}
};
Wonderful solution, Jay, +1!
绝妙的解决方案,杰,+1!
回答by The Finest Artist
Here is my custom EditText to detect whether keyboard is showing or not
这是我的自定义 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);
}
}
回答by Leo Droidcoder
It's 2019 now...
So I created a more neat solution with Kotlin
现在是 2019 年......
所以我用 Kotlin 创建了一个更简洁的解决方案
1.Create an extension function:
1.创建扩展函数:
fun Activity.addKeyboardToggleListener(onKeyboardToggleAction: (shown: Boolean) -> Unit): KeyboardToggleListener? {
val root = findViewById<View>(android.R.id.content)
val listener = KeyboardToggleListener(root, onKeyboardToggleAction)
return root?.viewTreeObserver?.run {
addOnGlobalLayoutListener(listener)
listener
}
}
2.Where the toggle listener is:
2.切换监听器在哪里:
open class KeyboardToggleListener(
private val root: View?,
private val onKeyboardToggleAction: (shown: Boolean) -> Unit
) : ViewTreeObserver.OnGlobalLayoutListener {
private var shown = false
override fun onGlobalLayout() {
root?.run {
val heightDiff = rootView.height - height
val keyboardShown = heightDiff > dpToPx(200f)
if (shown != keyboardShown) {
onKeyboardToggleAction.invoke(keyboardShown)
shown = keyboardShown
}
}
}
}
fun View.dpToPx(dp: Float) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.displayMetrics).roundToInt()
3.Use it in any Activity as simple as this:
3.在任何活动中使用它就像这样简单:
addKeyboardToggleListener {shown ->
// hurray! Now you know when the keyboard is shown and hidden!!
}
回答by farhad.kargaran
Just create a class that extends Edittext and use that edittext in your code, you should just override the following method in the custom edittext:
只需创建一个扩展 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;}
回答by Rubin Yoo
Here's a solution with the key listener. I have no idea why this works but OnKeyListener works if you just purely override onKeyPreIme on your custom EditText.
这是带有关键侦听器的解决方案。我不知道为什么会这样,但是 OnKeyListener 可以工作,如果你只是在你的自定义 EditText 上纯粹覆盖 onKeyPreIme。
SomeClass.java
类.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);
}
回答by Steven Evers
For anyone looking to do the same in Xamarin, I've translated some of the top answers as it's a bit different. I created a gist herebut summarizing, you create a custom EditText and override OnKeyPreIme
like so:
对于希望在 Xamarin 中做同样事情的人,我已经翻译了一些最重要的答案,因为它有点不同。我在这里创建了一个要点,但总结一下,您创建了一个自定义 EditText 并OnKeyPreIme
像这样覆盖:
public class CustomEditText : EditText
{
public event EventHandler BackPressed;
// ...
public override bool OnKeyPreIme([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
if (e.KeyCode == Keycode.Back && e.Action == KeyEventActions.Up)
{
BackPressed?.Invoke(this, new EventArgs());
}
return base.OnKeyPreIme(keyCode, e);
}
}
... and then in the view...
......然后在视图中......
editText = FindViewById<CustomEditText>(Resource.Id.MyEditText);
editText.BackPressed += (s, e) =>
{
// <insert code here>
};
回答by bmjohns
Using @olivier_sdg's answer, but converted to Kotlin:
使用@olivier_sdg 的答案,但转换为 Kotlin:
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)
}
回答by Bali
hideSoftInputFromWindow
returns true when keyboard closes use it's value to detect keyboard close in android
hideSoftInputFromWindow
键盘关闭时返回 true 使用它的值来检测 android 中的键盘关闭
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.hideSoftInputFromWindow(findFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS)) {
//keyboard is closed now do what you need here
}