You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让RecyclerView适配器内的EditText在Fragment显示时自动聚焦

问题描述

我有一个包含RecyclerView控件的Fragment,该RecyclerView绑定了头部适配器HeaderAdapter,适配器布局内包含一个EditText控件。
当Fragment进入可视区域时,我希望这个EditText能够自动聚焦(即自动弹出软键盘)。

对应Fragment的初始实现代码如下:

public class My Fragment extends Fragment {

    private LinearLayoutManager layoutManager;

    private FeedRecyclerView recyclerView;

    private PostAdapter postAdapter;

    private ConcatAdapter concatAdapter;

    private HeaderAdapter headerAdapter;

    private List<Post> postData = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_fragment, parent, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        recyclerView = view.findViewById(R.id.recycler_view);

        layoutManager = new FeedLinearLayoutManager(getContext());

        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        // This is the adapter that contains the EditText
        headerAdapter = new HeaderAdapter(getContext());

        postAdapter = new PostAdapter(getContext(), postData, layoutManager);

        concatAdapter = new ConcatAdapter();
        recyclerView.setAdapter(concatAdapter);

        concatAdapter.addAdapter(searchHeaderAdapter);
    }
}

头部适配器类HeaderAdapter的实现代码如下:

public class HeaderAdapter extends RecyclerView.Adapter<HeaderAdapter.ViewHolder> {

    private Context context;

    public HeaderAdapter(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_header, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        //
    }

    @Override
    public long getItemId(int position) {
        return 1;
    }

    @Override
    public int getItemCount() {
        return 1;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public EditText myEditText;

        public ViewHolder(View v) {
            super(v);

            myEditText = v.findViewById(R.id.my_edit_text);
        }
    }

}

需要实现在Fragment展示时,HeaderAdapter内的EditText自动聚焦并弹出软键盘。

实现方案

首先修正初始代码的两处笔误,否则功能无法正常运行:

  • 类名My Fragment存在非法空格,改为MyFragment
  • concatAdapter.addAdapter(searchHeaderAdapter)引用了不存在的变量,改为concatAdapter.addAdapter(headerAdapter),确保头部适配器被正确添加到适配器链中

之后按以下步骤实现自动聚焦:

  1. 配置宿主Activity软键盘模式
    打开AndroidManifest.xml,找到承载该Fragment的Activity节点,不要配置android:windowSoftInputMode="stateHidden"或stateAlwaysHidden"(这两个属性会强制进入页面时隐藏软键盘),推荐添加adjustResize属性避免软键盘遮挡布局:
<activity
    android:name=".YourHostActivity"
    android:windowSoftInputMode="adjustResize" />
  1. 在Fragment可见时执行聚焦逻辑
    不要在onViewCreated或适配器的onBindViewHolder中直接调用聚焦方法:前者执行时RecyclerView还未完成布局,拿不到头部ViewHolder的EditText实例;后者可能在页面预加载时触发,导致非可见状态下乱弹键盘。
    正确做法是重写Fragment的onResume方法(该方法触发时Fragment已进入可视状态),通过post等待RecyclerView布局完成后再查找控件、执行聚焦和弹键盘操作:
// 导入需要的依赖类
import android.content.Context;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

@Override
public void onResume() {
    super.onResume();
    recyclerView.post(() -> {
        // HeaderAdapter是第一个添加到ConcatAdapter的适配器,对应item位置为0
        HeaderAdapter.ViewHolder headerHolder = (HeaderAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(0);
        if (headerHolder != null) {
            EditText targetEt = headerHolder.myEditText;
            // 让EditText获取焦点
            targetEt.requestFocus();
            // 调起软键盘
            InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null) {
                imm.showSoftInput(targetEt, InputMethodManager.SHOW_IMPLICIT);
            }
        }
    });
}
  1. (可选)离开页面时自动收起软键盘
    如果需要Fragment切到后台时自动收起键盘,可以重写onPause方法添加对应逻辑:
@Override
public void onPause() {
    super.onPause();
    InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm != null && getView() != null) {
        imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
    }
}

注意:如果后续调整了ConcatAdapter的add顺序,HeaderAdapter不在第一个位置,需要把代码里查找ViewHolder的位置参数0改成HeaderAdapter对应的实际起始位置即可。

内容的提问来源于stack exchange,提问作者user1695123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:06:23