在我的应用中,我创建了一个项目列表,其中每个项目的名称都可以编辑,类似于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());
}
}
}