自定义AppCompatEditText子类ComplexEditText点击无法唤起软键盘求助
解决自定义AppCompatEditText点击不弹出软键盘的问题
我仔细看了你的ComplexEditText实现和遇到的问题,试过的方法都没生效,核心问题出在两个地方:触摸事件的拦截逻辑干扰了焦点获取,以及软键盘弹出的时机不对。下面是具体的修复方案:
1. 确保View具备正确的焦点属性
首先,在init()方法里补充设置focusableInTouchMode,这是EditText触摸时获取焦点的关键属性,之前你可能漏了这个:
void init() { mClearButtonImage = ResourcesCompat.getDrawable(getResources(), R.mipmap.delete_button, null); setBackground(getResources().getDrawable(R.drawable.backgroundedittext)); setPadding((int) (16 * scale), (int) (10 * scale), (int) (17 * scale), (int) (13 * scale)); // 补充焦点相关设置 setFocusable(true); setFocusableInTouchMode(true); // 必须设置这个,才能触摸获取焦点 setShowSoftInputOnFocus(true); // 移除这里的imm.showSoftInput调用,时机不对 // InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); // imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT); // ... 原有触摸监听和文本监听逻辑 }
2. 修复OnTouchListener的事件拦截逻辑
你的触摸监听里,部分分支的返回值会干扰View获取焦点。修改逻辑:只有点击清除按钮时才拦截事件,其他情况让View正常处理触摸事件来获取焦点:
setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.e("focus", getFullName() + " _ " + String.valueOf(getShowSoftInputOnFocus())); if ((getCompoundDrawablesRelative()[2] != null)) { float clearButtonStart; float clearButtonEnd; boolean isClearButtonClicked = false; if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { clearButtonEnd = mClearButtonImage.getIntrinsicWidth() + getPaddingStart(); if (event.getX() < clearButtonEnd) { isClearButtonClicked = true; } } else { clearButtonStart = (getWidth() - getPaddingEnd() - mClearButtonImage.getIntrinsicWidth()); if (event.getX() > clearButtonStart) { isClearButtonClicked = true; } } if (isClearButtonClicked) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mClearButtonImage = ResourcesCompat.getDrawable(getResources(), R.mipmap.delete_button, null); showClearButton(); } if (event.getAction() == MotionEvent.ACTION_UP) { mClearButtonImage = ResourcesCompat.getDrawable(getResources(), R.mipmap.delete_button, null); getText().clear(); hideClearButton(); } // 点击清除按钮时返回true,拦截事件 return true; } } // 非清除按钮区域,返回false让View处理触摸事件,确保能获取焦点 return false; } });
3. 正确时机触发软键盘弹出
之前在init()里调用showSoftInput时,View还没被添加到窗口,所以无效。我们把弹出逻辑移到onFocusChanged方法中,当View获取焦点时再触发:
@Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(focused, direction, previouslyFocusedRect); if (focused) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); // 确保软键盘弹出 imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT); } }
额外检查
- 确保你的
backgroundedittextdrawable没有设置android:clickable="true",否则会抢占View的焦点事件; - 保持AndroidManifest中Activity的
android:windowSoftInputMode="stateVisible"设置不变即可。
按照上面的修改后,点击ComplexEditText时应该能正常获取焦点并弹出软键盘了。
内容的提问来源于stack exchange,提问作者Dorokhov Yegor
相关产品推荐
相关产品推荐

