在我的应用中,我创建了一个项目列表,其中每个项目的名称都可以编辑,类似于Google Keep . 下面是列表中每个项目的布局 .

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
>
<CheckBox
    android:layout_centerVertical="true"
    android:layout_alignParentLeft="true"
    android:id="@+id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<EditText
    android:background="@null"
    android:id="@+id/et_item"
    android:layout_toRightOf="@id/checkbox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
<ImageButton
    android:layout_alignParentRight="true"
    android:id="@+id/button_remove_item"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:background="@android:color/transparent"
    android:contentDescription="@string/remove_item_option"
    android:src="@drawable/ic_action_remove"
    android:visibility="gone" />

我正在onFocusChange上保存特定项目的已编辑名称,如下所示 .

holder.mEtItemName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if(!b)
                {
                    Toast.makeText(view.getContext(),"saving:"+holder.mEtItemName.getText().toString(),Toast.LENGTH_LONG).show();
                    updateItem(model.getItemId(),holder.mEtItemName.getText().toString(),null);
                }
                else
                {
                    mCurrentKey=model.getItemId();
                }

            }
        });

但是,如果按下后退按钮编辑特定项目(对于所选的EditText没有更改焦点),我正在尝试保存此项目的新文本 . 现在因为没有调用onFocusChange(),我在EditText中添加了一个TextChangedListener,这样我就可以将新文本保存在某个全局变量中 .

class ItemEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            mCurrentItemName=editable.toString();
            mCurrentPositionList=position;

            Log.d(TAG, "afterTextChanged: --------"+mCurrentPositionList);
            items.get(position).setItemName(editable.toString());

        }
    }

但是,在最初填充列表时以及按下后退按钮时,会在随机位置调用afterTextChanged() . 例如,如果正在编辑位置= 7的edittext并按下后面,则afterTextChanged()的Log.d语句将打印如下所示的内容 -

D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------7
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------9
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------10
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------11
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------12
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------13
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------14
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------15
 D/ActivityCreateUpdate: afterTextChanged: --------0
 D/ActivityCreateUpdate: afterTextChanged: --------16
 D/ActivityCreateUpdate: afterTextChanged: --------0

因此,我在最后持有一些错误的值来保存 . 这与回收意见有关吗?为什么afterTextChanged()被随机调用?添加TextChangedListener列表项是个坏主意吗?如果是的话,在这种情况下你的建议是什么?

适配器的完整代码:

class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ItemViewHolder>
{

    private ArrayList<ShoppingListItem> items;

    public ItemsAdapter(ArrayList<ShoppingListItem> itemsList) {

        items = itemsList;
    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.each_item_add_list,parent,false);
        return new ItemViewHolder(view,new ItemEditTextListener());
    }
    public void addItem()
    {
        items.add(new ShoppingListItem());
        notifyItemInserted(items.size());
    }

    @Override
    public void onBindViewHolder(final ItemViewHolder holder, final int position) {
        final ShoppingListItem model=items.get(position);
        holder.setIsRecyclable(false);

        holder.mEtItemName.setText(model.getItemName());
        holder.myItemEditTextListener.updatePosition(position);

        if(model.getBoughtBy()!=null)
        {
            holder.mCheckBox.setChecked(true);
            StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
            Spannable spannable = (Spannable) holder.mEtItemName.getText();
            spannable.setSpan(STRIKE_THROUGH_SPAN, 0, holder.mEtItemName.getText().toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        }
        else
        {
            holder.mCheckBox.setChecked(false);
            holder.mEtItemName.setText(model.getItemName());

        }

        holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                if(b)
                {
                    updateItem(model.getItemId(),holder.mEtItemName.getText().toString(),mEncodedEmail);

                    StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
                    Spannable spannable = (Spannable) holder.mEtItemName.getText();
                    spannable.setSpan(STRIKE_THROUGH_SPAN, 0, holder.mEtItemName.getText().toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

                }
                else
                {

                    holder.mEtItemName.setText(model.getItemName());

                }
            }
        });


        holder.mEtItemName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if(!b)
                {
                    Toast.makeText(view.getContext(),"saving:"+holder.mEtItemName.getText().toString(),Toast.LENGTH_LONG).show();
                    updateItem(model.getItemId(),holder.mEtItemName.getText().toString(),null);
                }
                else
                {
                    mCurrentKey=model.getItemId();
                }

            }
        });
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    class ItemViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.et_item)
        EditText mEtItemName;

        @BindView(R.id.button_remove_item)
        ImageButton mIBRemoveItem;

        @BindView(R.id.checkbox)
        CheckBox mCheckBox;

        ItemEditTextListener myItemEditTextListener;

        public ItemViewHolder(View itemView, ItemEditTextListener myItemEditTextListener) {
            super(itemView);
            ButterKnife.bind(this,itemView);

            this.myItemEditTextListener = myItemEditTextListener;
            mEtItemName.addTextChangedListener(myItemEditTextListener);
        }
    }

    class ItemEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            mCurrentItemName=editable.toString();
            mCurrentPositionList=position;

            Log.d(TAG, "afterTextChanged: --------"+mCurrentPositionList);
            items.get(position).setItemName(editable.toString());

        }
    }
}