Android:EditText点击弹键盘时光标首次异常上移问题求助
我来帮你搞定这个首次点击EditText时光标异常偏移的问题,考虑到你不能移除android:descendantFocusability="afterDescendants"(因为要防止Adapter中EditText重建),以下几个方案应该能帮到你:
方案一:手动校正EditText焦点获取时的光标位置
在你的Adapter中,给每个EditText设置焦点变化监听器,当它首次获取焦点时,手动将光标定位到正确位置,并强制触发布局更新。这样可以抵消首次点击时的位置计算错误:
EditText editText = view.findViewById(R.id.input); editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { // 用post确保在布局完成后执行光标校正 editText.post(() -> { int textLength = editText.getText().length(); // 光标移到文本末尾(如果有内容),否则留在起始位置 editText.setSelection(textLength > 0 ? textLength : 0); // 强制EditText重新布局,确保位置正确 editText.requestLayout(); }); } } });
方案二:调整Activity的软键盘显示模式
在AndroidManifest.xml中,给你的MainActivity添加软键盘模式配置,让系统在键盘弹出时正确调整布局,避免光标位置计算异常:
<activity android:name=".view.MainActivity" android:windowSoftInputMode="adjustResize|stateHidden"> <!-- 其他配置 --> </activity>
adjustResize会让Activity的窗口大小随键盘弹出而调整,stateHidden确保键盘默认不显示,只有点击EditText时才弹出,这能减少首次点击时的布局冲突。
方案三:优化ExpandableListView的焦点与滚动逻辑
因为你的EditText嵌套在ExpandableListView中,首次点击时列表可能没有正确滚动到EditText的可见位置,导致光标偏移。可以给ExpandableListView添加焦点监听,确保失去焦点时(EditText获取焦点),列表能正确滚动到对应的子项:
ExpandableListView listView = findViewById(R.id.listview); listView.setOnFocusChangeListener((v, hasFocus) -> { if (!hasFocus) { listView.post(() -> { long packedPos = listView.getSelectedPosition(); int groupPos = ExpandableListView.getPackedPositionGroup(packedPos); int childPos = ExpandableListView.getPackedPositionChild(packedPos); if (groupPos != -1 && childPos != -1) { // 展开对应的组,并滚动到子项位置 listView.expandGroup(groupPos); listView.setSelectedChild(groupPos, childPos, true); } }); } });
问题原因分析
你遇到的问题主要是android:descendantFocusability="afterDescendants"导致的焦点顺序变化,首次点击EditText时,键盘弹出的时机与布局更新的时机不匹配,系统计算光标位置时没有考虑到键盘弹出后的布局调整,从而出现偏移。上面的方案分别从光标校正、布局调整、列表滚动三个角度解决这个时序问题。
内容的提问来源于stack exchange,提问作者Mingorto

