recyclerview 中item多行多列edittext切换,及切换下一个item中的edittext问题

上一篇文章已经讲过,关于edittext切换焦点,将光标设置到最后一位的问题。有兴趣的朋友可以看我上一篇文章

今天主要讲recyclerview中多行多列的edittext切换及切换下一个item中的edittext问题

先看看在不加任何处理的情况下的edittext在recyclerview中切换效果(当然,edittext的前提需要设置singleline=true,maxlines=1,这样才能激活键盘中的切换下一项功能)
在这里插入图片描述

从图中大家可以看到,在没有任何处理的情况下,光标直接切换到底部的edittext,而不是我们期望的下一个edittext。究其原因,是因为键盘的“下一项”触发的是“nextfocusdown”事件,因为默认的键盘定义中只存在nextfocusleft,nextfocusright,nextfocusup,nextfocusdown,即上下左右。如果我们要切换到我们期望的下一个 需要在上一个设置nextFocusDown属性,指定切换的控件的id

例子 : nextFocusDown= @+id/edit2

接下来看效果

在这里插入图片描述

从图中可以看到,点击切换的时候,虽然是按我设置的顺序切换,但是没有切换到下一个itemview中。这是因为我在最后一个Edittext中设置了 nextFocusDown= @+id/edit1,所有到最后一个的时候就切换到了第一个。接下来去掉最后一个edittext中的设置看效果

在这里插入图片描述

从图中可以看到,在第一个itemview中的最后一个edittext切换时,并没有切换到下一个itemview中的第一个edittext,依然还是切换到了它底部的edittext。那么改如何解决这个问题呢

这里就需要重写LinearLayoutManager中的 onInterceptFocusSearch

先说一下代码逻辑,onInterceptFocusSearch相当于是焦点切换的监听。在这个方法中,我们先获取当前焦点的itemview的下标且不是最后一个,然后判断edittext是否为itemview中的最后一个,满足这些条件时,获取下一个itemview中的第一个edittext并返回,这就能成功解决了此问题
直接上代码
public class FocusLinearlayoutManager extends LinearLayoutManager {

    public FocusLinearlayoutManager(Context context) {
        super(context);
    }


    @Nullable
    @Override
    public View onInterceptFocusSearch(@NonNull View focused, int direction) {
        if(focused instanceof EditText){
            EditText editText = ((EditText) focused);
            //光标移入文件末尾
            editText.setSelection(editText.getText().length());
        }
        switch (direction) {
            case View.FOCUS_DOWN:
                //单个列表的最后一个
                if(isLast((EditText) focused,(ViewGroup)getFocusedChild())){
                    for(int i = 0 ; i < getItemCount(); i ++){
                        if(getChildAt(i) == getFocusedChild()){
                            if(i < getItemCount() - 1){
                                View firstEdit = getFirstEdit((ViewGroup) getChildAt(i + 1));
                                return firstEdit;
                            }
                            break;
                        }
                    }
                }
        }
        return super.onInterceptFocusSearch(focused,direction);
    }

    /**
     * 获取第一个edit
     * @param viewGroup
     * @return
     */
    private View getFirstEdit(ViewGroup viewGroup){
        for(int i = 0 ; i < viewGroup.getChildCount() ; i ++){
            View view = viewGroup.getChildAt(i);
            if(view instanceof EditText){
                return view;
            }else if(view instanceof ViewGroup){
                View firstEdit = getFirstEdit((ViewGroup) view);
                if(firstEdit != null) {
                    return firstEdit;
                }
            }
        }
        return null;

    }

    /**
     * 是否为最后一个
     * @param editText
     * @param viewGroup
     * @return
     */
    private boolean isLast(EditText editText,ViewGroup viewGroup){
        getFocusedChild();
        List<EditText> list = new ArrayList<>();
        getEdits(list,viewGroup);
        if(list.indexOf(editText) == list.size() -1){
            return true;
        }
        return false;
    }

    /**
     * 获取所有edit
     * @param list
     * @param viewGroup
     */
    private void  getEdits(List<EditText> list,ViewGroup viewGroup){
        for(int i = 0 ; i < viewGroup.getChildCount() ; i ++){
            View view = viewGroup.getChildAt(i);
            if(view instanceof EditText){
                list.add((EditText) view);
            }else if(view instanceof ViewGroup){
                getEdits(list, (ViewGroup) view);
            }
        }
    }

}

此类 与recyclerview设置layoutmanager代码相同

recyclerView.setLayoutManager(new FocusLinearlayoutManager(mContext));

接下来看效果

在这里插入图片描述

最后推荐一个我自己写的MVVM开源项目《Open MVVM》(想加扣扣讨论群请进入文章结尾查看群号)

有问题请私信,留言,或者发送邮件到我扣扣邮箱 qingingrunt2010

到此 功能就写完了,也可以加QQ群交流技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要设置RecyclerViewEditText的焦点,您可以在RecyclerView的Adapter进行操作。以下是一种常见的方式: 1. 在RecyclerView的Adapter定义一个变量来跟踪当前具有焦点的EditText位置。 2. 在Adapter的onBindViewHolder方法,为每个EditText设置一个唯一的标识符(例如使用item的位置或ID)。 3. 在EditText的焦点变化监听器,更新当前具有焦点的EditText位置,并通知Adapter进行刷新。 4. 在Adapter的onBindViewHolder方法,检查当前位置是否与具有焦点的EditText位置匹配。如果匹配,则将EditText设置为具有焦点;否则,清除EditText的焦点。 这是一个示例代码: ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private int focusedPosition = RecyclerView.NO_POSITION; @Override public void onBindViewHolder(ViewHolder holder, int position) { // 设置唯一标识符 holder.editText.setTag(position); // 设置焦点变化监听器 holder.editText.setOnFocusChangeListener((view, hasFocus) -> { int pos = (int) view.getTag(); if (hasFocus) { focusedPosition = pos; } }); // 检查当前位置是否与具有焦点的EditText位置匹配 if (position == focusedPosition) { holder.editText.requestFocus(); } else { holder.editText.clearFocus(); } } // 其他代码... static class ViewHolder extends RecyclerView.ViewHolder { EditText editText; ViewHolder(View itemView) { super(itemView); editText = itemView.findViewById(R.id.edit_text); } } } ``` 通过这种方式,您可以在RecyclerView设置EditText的焦点,并确保焦点在滚动或重用时正确处理。希望对您有所帮助!如有任何疑问,请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值