按下回车键后如何将焦点移动到RecyclerView新增的EditText子项
解决方案
核心原因
设置imeOptions无效是因为新插入的列表项还没完成RecyclerView的布局渲染,此时EditText还未挂载到窗口,直接请求焦点不会生效;另外onKey事件默认会在按下和抬起各触发一次,不加判断会重复新增条目。
具体修改
1. 先在适配器中增加构造参数,传入RecyclerView和上下文实例,方便后续操作。
2. 修改onBindViewHolder逻辑,修改后代码如下:
@Override public void onBindViewHolder(@NonNull Adapter.ViewHolder holder, int position) { // 先移除旧的文字监听,避免滚动时数据错位 holder.text.removeTextChangedListener((TextWatcher) holder.text.getTag()); TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { // 用getAdapterPosition获取实时位置,避免列表滚动后position错位 int currentPos = holder.getAdapterPosition(); if (currentPos != RecyclerView.NO_POSITION) { list.get(currentPos).setText(s.toString()); } } }; holder.text.addTextChangedListener(textWatcher); holder.text.setTag(textWatcher); holder.text.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // 仅处理回车按下事件,避免重复触发 if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) { int currentPos = holder.getAdapterPosition(); if (currentPos == RecyclerView.NO_POSITION) return false; int newItemPos = currentPos + 1; // 插入新项到当前项下方 list.add(newItemPos, new EdittextItem()); notifyItemInserted(newItemPos); // 等待RecyclerView完成新项布局后执行焦点操作 holder.itemView.post(() -> { // 滚动到新项位置 recyclerView.smoothScrollToPosition(newItemPos); // 等待滚动完成后请求焦点 recyclerView.postDelayed(() -> { ViewHolder newItemHolder = (ViewHolder) recyclerView.findViewHolderForAdapterPosition(newItemPos); if (newItemHolder != null) { newItemHolder.text.requestFocus(); // 光标移到输入框末尾 newItemHolder.text.setSelection(newItemHolder.text.getText().length()); // 自动弹出软键盘 InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(newItemHolder.text, InputMethodManager.SHOW_IMPLICIT); } }, 100); }); // 消费回车事件,避免输入框自动换行 return true; } return false; } }); }
补充注意事项
确认EditText布局属性开启了可聚焦配置:
<EditText android:id="@+id/text" android:focusable="true" android:focusableInTouchMode="true" android:imeOptions="actionNext" .../>
如果觉得100ms延迟体验不好,可以给RecyclerView添加滚动监听,在滚动完成后再执行焦点请求逻辑,适配性更好。
内容的提问来源于stack exchange,提问作者Dep1111
相关产品推荐
相关产品推荐

