我的视图中有一个EditText小部件.当用户选择EditText小部件时,我会显示一些指令并显示软键盘.
我使用OnEditorActionListener来检测用户何时完成文本输入,然后关闭键盘,隐藏指令并执行某些操作.
我的问题是当用户按下BACK键关闭键盘时.操作系统解除键盘,但我的指令(我需要隐藏)仍然可见.
我已经尝试重写OnKeyDown,但是当使用BACK按钮关闭键盘时,似乎没有调用.
我已经尝试在EditText小部件上设置OnKeyListener,但似乎也没有调用.
如何检测软键盘何时被解除?
小智 159
我知道这样做的方法.对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);
}
Run Code Online (Sandbox Code Playgroud)
以下是有关如何使用自定义视图的链接(当您将EditText子类化时):http: //developer.android.com/guide/topics/ui/custom-components.html
oli*_*sdg 121
周杰伦,你的解决方案很好!谢谢 :)
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);
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ght 17
我通过调用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);
}
};
Run Code Online (Sandbox Code Playgroud)
精彩的解决方案,Jay,+ 1!
The*_*ist 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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在是 2019 年......
所以我用 Kotlin 创建了一个更简洁的解决方案
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
}
}
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
3.在任何活动中使用它就像这样简单:
addKeyboardToggleListener {shown ->
// hurray! Now you know when the keyboard is shown and hidden!!
}
Run Code Online (Sandbox Code Playgroud)
使用@olivier_sdg 的答案,但转换为 Kotlin:
class KeyboardEditText : AppCompatEditText {
var listener: Listener? = 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) {
listener?.onImeBack(this)
}
return super.dispatchKeyEvent(event)
}
interface Listener {
fun onImeBack(editText: KeyboardEditText)
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
keyboardEditText.listener = object : KeyboardEditText.Listener {
override fun onImeBack(editText: KeyboardEditText) {
//Back detected
}
}
Run Code Online (Sandbox Code Playgroud)
只需创建一个扩展 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;}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
72939 次 |
最近记录: |