Answers:
我知道一种方法。子类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
onKeyPreIme吗?还是有一个特殊的原因使它不是如此?
SearchView,请参阅stackoverflow.com/questions/9629313/...
周杰伦,您的解决方案很好!谢谢 :)
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);
}
KeyEvent.ACTION_UP吗?
android.support.v7.widget.AppCompatEditText以进行着色。
AppCompatEditText适用于androidx
这是我自定义的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);
}
}
现在是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
}
}
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. 像这样简单地在任何活动中使用它:
addKeyboardToggleListener {shown ->
// hurray! Now you know when the keyboard is shown and hidden!!
}
只需创建一个扩展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;}
这是关键侦听器的解决方案。我不知道为什么会这样,但是如果您只是在自定义EditText上重写onKeyPreIme,则OnKeyListener可以工作。
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);
}
使用@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)
}
}
用法:
keyboardEditText.listener = object : KeyboardEditText.Listener {
override fun onImeBack(editText: KeyboardEditText) {
//Back detected
}
}
对于希望在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);
}
}
...然后在视图中...
editText = FindViewById<CustomEditText>(Resource.Id.MyEditText);
editText.BackPressed += (s, e) =>
{
// <insert code here>
};
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
}