欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

RecycleView使用EditText的数据和焦点错乱问题解决方案

程序员文章站 2022-03-11 22:57:30
RecycleView是常用的列表控件,在日常的开发中使用频率很高,使用起来很方便,只要设置好条目布局和数据就可以完美的展示数据。EditText是常用的输入控件,用于用户的数据输入。二者本来各自使用都很容易,但是如果放到一起就出现问题,条目的复用导致EditText输入的内容出现错乱,焦点的获取也混乱了,令很多新手大为头疼。基本的思路是要在条目的可见和隐藏时处理好焦点的问题,要将操作的EditText的位置坐标记录下来,进行有效管理,还有将输入框的显示和隐藏也管理起来。解决的代码本身并不复杂,注释也标...

RecycleView是常用的列表控件,在日常的开发中使用频率很高,使用起来很方便,只要设置好条目布局和数据就可以完美的展示数据。EditText是常用的输入控件,用于用户的数据输入。二者本来各自使用都很容易,但是如果放到一起就出现问题,条目的复用导致EditText输入的内容出现错乱,焦点的获取也混乱了,令很多新手大为头疼。

基本的思路是要在条目的可见和隐藏时处理好焦点的问题,要将操作的EditText的位置坐标记录下来,进行有效管理,还有将输入框的显示和隐藏也管理起来。解决的代码本身并不复杂,注释也标识出来了。之前写过一个List View和EditText搭配使用的文章,这里算是更新吧,并且输入框也增加了多个输入框的处理逻辑。

RecycleView使用EditText的数据和焦点错乱问题解决方案

核心的Adapter代码如下:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String TAG="MyAdapter";
    private List<ItemDataEntity> list;
    private Context mContext;
    private final InputMethodManager inputMethodManager;
    //edittext的焦点position位置
    int etFocusPos = -1;
    private int idSelectView=-1;

    public MyAdapter(List<ItemDataEntity> list, Context mContext) {
        this.list = list;
        this.mContext = mContext;
        inputMethodManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    }


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, null);
        ViewHolder viewHolder = new ViewHolder(inflate);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        holder.tvNum.setText("序号:"+list.get(position).getNum());
        holder.tvName.setText("姓名:"+list.get(position).getName());
        holder.etAge.setText(list.get(position).getAge());
        holder.etaddress.setText(list.get(position).getAddress());
        holder.etaddress.addTextChangedListener(textWatcher);
        holder.etAge.addTextChangedListener(textWatcher);
        //当焦点获取或取消时
        holder.etaddress.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if (b){
                    idSelectView = view.getId();
                    etFocusPos = position;
                    Log.i(TAG,"etFocusPos焦点选中-"+etFocusPos);
                }
            }
        });
        //当焦点获取或取消时
        holder.etAge.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if (b){
                    idSelectView = view.getId();
                    etFocusPos = position;
                    Log.i(TAG,"etFocusPos焦点选中-"+etFocusPos);
                }
            }
        });
    }

    /**
     * 当适配器创建的view(即列表项view)划出屏幕,不可见时调用
     * @param holder
     */
    @Override
    public void onViewDetachedFromWindow(ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        Log.i(TAG,"隐藏item="+holder.getAdapterPosition());
        //根据点击的不同editextview 处理焦点和监听
        if (idSelectView==R.id.et_address){
            holder.etaddress.removeTextChangedListener(textWatcher);
            holder.etaddress.clearFocus();
        }else if (idSelectView==R.id.et_age){
            holder.etAge.removeTextChangedListener(textWatcher);
            holder.etAge.clearFocus();
        }
        //当条目不可见时,重置焦点position,隐藏键盘
        if (etFocusPos == holder.getAdapterPosition()) {
            inputMethodManager.hideSoftInputFromWindow(((ViewHolder) holder).etaddress.getWindowToken(), 0);
            etFocusPos=-1;
        }
    }

    /**
     * edittextview的文本监听
     */
    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) {
            //每次修改文字后,保存在数据集合中
            Log.i(TAG,"index="+etFocusPos+",save="+s.toString());
            if (!TextUtils.isEmpty(s.toString())&&etFocusPos!=-1){
                if (idSelectView==R.id.et_address){
                    list.get(etFocusPos).setAddress(s.toString());
                }else if (idSelectView==R.id.et_age){
                    list.get(etFocusPos).setAge(s.toString());
                }
            }
        }
    };

    /**
     * 当列表项出现到可视界面的时候调用
     * @param holder
     */
    @Override
    public void onViewAttachedToWindow(ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        Log.i(TAG,"显示item="+holder.getAdapterPosition());
        if (idSelectView==R.id.et_age){
            holder.etAge.addTextChangedListener(textWatcher);
        }else if (idSelectView==R.id.et_address){
            holder.etaddress.addTextChangedListener(textWatcher);
        }
        //根据点击的位置,处理焦点和光标位置
        if (etFocusPos == holder.getAdapterPosition()) {
            if (idSelectView==R.id.et_age){
                holder.etAge.requestFocus();
                holder.etAge.setSelection(holder.etAge.getText().length());
            }else if (idSelectView==R.id.et_address){
                holder.etaddress.requestFocus();
                holder.etaddress.setSelection(holder.etaddress.getText().length());
            }
        }
    }
    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        private TextView tvNum;
        private TextView tvName;
        private EditText etAge;
        private EditText etaddress;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tvNum = itemView.findViewById(R.id.tv_num);
            tvName = itemView.findViewById(R.id.tv_name);
            etAge = itemView.findViewById(R.id.et_age);
            etaddress = itemView.findViewById(R.id.et_address);
        }
    }
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    xmlns:tool="http://schemas.android.com/tools"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv_num"
        tool:text="001"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_marginLeft="10dp"
        tool:text="tom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/et_age"
        android:layout_marginLeft="10dp"
        android:layout_width="80dp"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/et_address"
        android:layout_marginLeft="10dp"
        android:layout_width="80dp"
        android:layout_height="wrap_content" />
</LinearLayout>

展示的逻辑:

ArrayList<ItemDataEntity> itemDataEntities = new ArrayList<>();
        for (int i=0;i<50;i++){
            ItemDataEntity itemDataEntity = new ItemDataEntity();
            itemDataEntity.setName("T"+i);
            itemDataEntity.setNum(""+i);
            itemDataEntities.add(itemDataEntity);
        }
        RecyclerView recyclerView=findViewById(R.id.recycleview);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplication());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        MyAdapter myAdapter = new MyAdapter(itemDataEntities, getApplication());
        recyclerView.setAdapter(myAdapter);

 

本文地址:https://blog.csdn.net/qiantanlong/article/details/108709516

相关标签: Android