public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (BaseUtil.isEnterKey(actionId, event)) {
onMaterialEnter(v.getText().toString());
}
return true;
}
在按键回车同样触发onEditorAction 返回true 然后发现其他编辑框为空,让他调用其他编辑框焦点,结果会立马调回来,哪怕post()
但是软键盘没有此问题。。
因此此种情况怕是要多延长几秒了。目前没想到解决办法。
2022-11-21 14:54:07
终于找到了解决办法,并且代码进行了进一步的封装,还可以防止快速点击,当按键回车返回了true,那么在onEditorActionListenre将不会触发,
另外如果onKey返回false,那么 onEditorAction分别会受到,按下,和抬起的按键事件。
/**
* Return true if you have consumed the action, else false.
*
* @param actionId
* @param event
* @return
*/
public static boolean isKeyEnter(int actionId, KeyEvent event) {
boolean result = actionId == EditorInfo.IME_ACTION_DONE ||
actionId == EditorInfo.IME_ACTION_NEXT ||
actionId == EditorInfo.IME_ACTION_GO ||
actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_SEND ||
(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_UP);
return result;
}
/**
* 1 回车抬起触发 0 回车按下触发, 其他 代表返回false,交给系统处理
*
* @param keyCode
* @param event
* @return
*/
public static int isHardKeyEnter(int keyCode, KeyEvent event) {
boolean result =
(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_UP);
if (result) {
return 1;
} else if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN) {
return 0;//自己处理消费
}
return -1;
}
public static void setOnEditorActionEnterAndScanListener(Activity activity, EditText editText, DialogUtils.INotify<EditText> iNotify) {
editText.setOnKeyListener((v, keyCode, event) -> {
int result = BaseUtil.isHardKeyEnter(keyCode, event);
if (result == 1) {//按键回车抬起
AppUtils.closeKeyboard(activity);
iNotify.onNotify(editText);
return true;
} else if (result == 0) {//按键回车按下
return true;
}
return false;
});
editText.setOnEditorActionListener((v, actionId, event) -> {
if (BaseUtil.isKeyEnter(actionId, event)) {
if (ButtonUtils.isFastDoubleClick(actionId)) {
return true;
}
AppUtils.closeKeyboard(activity);
iNotify.onNotify(editText);
}
return true;
});
}
但是又发现了一个问题,
假设第一个编辑框没重写设置,而第二个编辑框设置了,从第一个编辑框按键回车会自动触发第二个编辑框的onKeyEvent从而发起了逻辑,依然是有问题的,要从源头上禁止按键回车改变光标 才能彻底解决问题,
虽然无法调试源码但是根据自定义view重写获取焦点追踪到了调用的代码处,为textview的onKeyUp事件所触发。
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
|| shouldAdvanceFocusOnEnter()) {
if (!hasOnClickListeners()) {
View v = focusSearch(FOCUS_DOWN);
if (v != null) {
if (!v.requestFocus(FOCUS_DOWN)) {
throw new IllegalStateException("focus search returned a view "
+ "that wasn't able to take focus!");
}
super.onKeyUp(keyCode, event);
return true;
} else if ((event.getFlags()
& KeyEvent.FLAG_EDITOR_ACTION) != 0) {
InputMethodManager imm = getInputMethodManager();
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
}
}
另外也要满足inputtype =TYPE_CLASS_TEXT
之类
private boolean shouldAdvanceFocusOnEnter() {
if (getKeyListener() == null) {
return false;
}
if (mSingleLine) {
return true;
}
if (mEditor != null
&& (mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS)
== EditorInfo.TYPE_CLASS_TEXT) {
int variation = mEditor.mInputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT) {
return true;
}
}
return false;
}
2022-11-26 12:28:00
经过源码分析在onEdiAction里面 无论是down还是up全部返回true,这样就不会交给系统处理焦点了,
而响应逻辑就处理按下就好了。
第二个编辑框设置setOnEditActionListenlier然后立马写了尝试发起调用第一个编辑框的获取焦点,结果是 又跳回来了,
如果第一个编辑框没设置焦点相关事件,第二个 触发 第一个, 第一个又调用了 第二个的焦点,也就是第一个的onKeyUp触发,然后执行如下代码
if (!hasOnClickListeners()) {
View v = focusSearch(FOCUS_DOWN);
if (v != null) {
if (!v.requestFocus(FOCUS_DOWN)) {
又让第二个获取了焦点。
去掉input=text 或者非单行,则正常运行,因此目前处理起来有点棘手。
if (mSingleLine) {
return true;
}
if (mEditor != null
&& (mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS)
== EditorInfo.TYPE_CLASS_TEXT) {
int variation = mEditor.mInputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT) {
return true;
}
}
满足此条件
if (mEditor != null && mEditor.mInputContentType != null
&& mEditor.mInputContentType.onEditorActionListener != null
&& mEditor.mInputContentType.enterDown) {
mEditor.mInputContentType.enterDown = false;
if (mEditor.mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
return true;
}
}
目前第一个编辑框&& mEditor.mInputContentType !=
是空的。所以走了shouldAdvanceFocusOnEnter
最后总结,方法是有了,但是要改的地方太多不太现实。。
比如
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_ENTER){
return true;
}
这导致硬件回车无法触发光标下移事件
最后的调整版本 就是按键回车这种不应该立马回调,让事件流失掉,就不会连环触发另外一个的按键抬起事件了。
public static void setOnEditorActionEnterAndScanListener(Activity activity, EditText editText, DialogUtils.INotify<EditText> iNotify) {
editText.setOnKeyListener((v, keyCode, event) -> {
int result = BaseUtil.isHardKeyEnter(keyCode, event);
if (result == 1) {//按键回车抬起
if (BuildConfig.DEBUG) {
Log.w("Event", "down" + event.getDownTime() + event.getEventTime() + "," + event.getEventTime() + ",fucus:" + editText.hasFocus());
}
AppUtils.closeKeyboard(activity);
if (ButtonUtils.isFastDoubleClick(keyCode)) {
return true;
}
if (TextUtils.isEmpty(editText.getText().toString())) {
return true;
}
// return false;
//让事件延迟流失掉,这样再请求另外的焦点应该不会连锁反应了。
editText.postDelayed(new Runnable() {
@Override
public void run() {
iNotify.onNotify(editText);
}
}, 10);
return true;
} else if (result == 0) {//按键回车按下
return true;
}
return false;
});
editText.setOnEditorActionListener((v, actionId, event) -> {
if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
return true;
}
if (BaseUtil.isKeyEnterOrHardKeyPress(actionId, event)) {
AppUtils.closeKeyboard(activity);
if (ButtonUtils.isFastDoubleClick(actionId)) {
return true;
}
iNotify.onNotify(editText);
}
return true;
});
}
但是问题依然没解决,
2022-11-26 13:24:13
把抬起改成按下,就可以确保按下的时候百分百是当前的。
这次终于解决了,下班