OnDestroyActionMode() 中断了 onActionItemClicked()
OnDestroyActionMode() interrupted onActionItemClicked()
我有一个名为 delete 的操作项,它获取我创建的 ArrayList 并删除所有选中的联系人(基于我在 class 联系人中的布尔变量)。
当我点击删除时一切都很好,它是一个项目,但如果它超过 6 个项目,onDestroyActionMode 方法会中断我的 onActionItemClicked 方法并且一些项目不会被删除。我该如何解决?
这是我的代码:
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class ContactViewAdapter extends RecyclerView.Adapter<ContactViewAdapter.ContactViewHolder> {
private static final String TAG = "AKS";
private AppCompatActivity mActivity;
private List<Contact> contactList;
public ActionMode mActionMode = null;
public ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.action_mode_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_mode_delete:
for (int i = 0; i < contactList.size(); i++) {
Log.d(TAG, "size " + String.valueOf(contactList.size()));
if (contactList.get(i).isSelected) {
contactList.remove(i);
}
}
notifyDataSetChanged();
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
for (Contact c : contactList) {
c.isSelected = false;
Log.d(TAG, "onDestroyActionMode");
}
mActionMode.finish();
mActionMode = null;
notifyDataSetChanged();
}
};
public class ContactViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public TextView contactName;
public TextView contactMoneyOwed;
public ImageView contactPhoto;
public CheckBox isCheckedBox;
public ContactViewHolder(View v) {
super(v);
contactName = (TextView) itemView.findViewById(R.id.contact_name);
contactMoneyOwed = (TextView) itemView.findViewById(R.id.contact_money_owed);
contactPhoto = (ImageView) itemView.findViewById(R.id.contact_photo);
isCheckedBox = (CheckBox) itemView.findViewById(R.id.listItemCheckBox);
v.setOnClickListener(this);
v.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
boolean everythingIsUnchecked = true;
for (Contact c : contactList) {
if (c.isSelected) {
everythingIsUnchecked = false;
}
}
if (!everythingIsUnchecked) {
isCheckedBox.setChecked(!isCheckedBox.isChecked());
} else {
Toast.makeText(mActivity.getApplicationContext(), "Coming soon!", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onLongClick(View v) {
isCheckedBox.setChecked(true);
return true;
}
}
public ContactViewAdapter(List<Contact> contactList, AppCompatActivity activity) {
this.contactList = contactList;
this.mActivity = activity;
}
@Override
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ContactViewHolder(v);
}
@Override
public void onBindViewHolder(final ContactViewHolder contactViewHolder, final int position) {
contactViewHolder.contactName.setText(contactList.get(position).name);
contactViewHolder.contactMoneyOwed.setText(contactList.get(position).moneyOwed);
contactViewHolder.contactPhoto.setImageResource(contactList.get(position).photoID);
contactViewHolder.contactPhoto.setOnTouchListener(null);
contactViewHolder.contactPhoto.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
contactViewHolder.isCheckedBox.setChecked(true);
}
return true;
}
});
contactViewHolder.isCheckedBox.setOnCheckedChangeListener(null);
contactViewHolder.isCheckedBox.setChecked(contactList.get(position).isSelected);
if (contactViewHolder.isCheckedBox.isChecked()) {
contactViewHolder.contactPhoto.setVisibility(View.GONE);
contactViewHolder.isCheckedBox.setVisibility(View.VISIBLE);
} else {
contactViewHolder.isCheckedBox.setVisibility(View.GONE);
contactViewHolder.contactPhoto.setVisibility(View.VISIBLE);
}
contactViewHolder.isCheckedBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, String.valueOf(position));
contactList.get(position).isSelected = isChecked;
boolean everythingIsUnchecked = true;
for (Contact c : contactList) {
if (c.isSelected) {
everythingIsUnchecked = false;
}
}
if (mActionMode == null) {
mActionMode = mActivity.startActionMode(mActionModeCallback);
} else if (everythingIsUnchecked) {
mActionMode.finish();
mActionMode = null;
}
if (isChecked) {
contactViewHolder.contactPhoto.setVisibility(View.GONE);
contactViewHolder.isCheckedBox.setVisibility(View.VISIBLE);
} else {
contactViewHolder.isCheckedBox.setVisibility(View.GONE);
contactViewHolder.contactPhoto.setVisibility(View.VISIBLE);
}
}
});
}
@Override
public int getItemCount() {
return contactList.size();
}
}
这是我从日志中得到的:
10-03 19:47:23.181 1962-1962/com.example.andreassavva.expensemanager D/AKS: 0
10-03 19:47:23.413 1962-1962/com.example.andreassavva.expensemanager D/AKS: 1
10-03 19:47:23.789 1962-1962/com.example.andreassavva.expensemanager D/AKS: 2
10-03 19:47:24.067 1962-1962/com.example.andreassavva.expensemanager D/AKS: 3
10-03 19:47:24.453 1962-1962/com.example.andreassavva.expensemanager D/AKS: 4
10-03 19:47:25.115 1962-1962/com.example.andreassavva.expensemanager D/AKS: 5
10-03 19:47:26.350 1962-1962/com.example.andreassavva.expensemanager D/AKS: 6
10-03 19:47:26.734 1962-1962/com.example.andreassavva.expensemanager D/AKS: 7
10-03 19:47:27.046 1962-1962/com.example.andreassavva.expensemanager D/AKS: 8
10-03 19:47:27.468 1962-1962/com.example.andreassavva.expensemanager D/AKS: 9
10-03 19:47:27.812 1962-1962/com.example.andreassavva.expensemanager D/AKS: 10
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 11
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 10
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 9
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 8
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 7
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 6
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
ActionMode.finish()
呼叫 onDestroyActionMode()
。因此,从 onDestroyActionMode()
实现中删除对 finish()
的调用。新实现变为:
@Override
public void onDestroyActionMode(ActionMode mode) {
for (Contact c : contactList) {
c.isSelected = false;
Log.d(TAG, "onDestroyActionMode");
}
//mActionMode.finish();
mActionMode = null;
notifyDataSetChanged();
}
由于您在 onDestroyActionMode()
中调用 notifyDataSetChanged()
,请从 onActionItemClicked()
的实现中删除该调用。新的 onActionItemClicked()
实现变为:
编辑:
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_mode_delete:
Iterator<Contact> contactIterator = contactList.iterator();
while(contactIterator.hasNext()) {
Contact contact = contactIterator.next();
if (contact.isSelected) {
contactIterator.remove();
}
}
//notifyDataSetChanged();
mode.finish();// This calls 'onDestroyActionMode()'
// and it will notify the data set change.
return true;
default:
return false;
}
}
想通了。我的 for 循环很烂。我需要将其更改为
for (int i = contactList.size() - 1; i >= 0; i--) {
if (contactList.get(i).isSelected()) {
contactList.remove(i);
}
}
相反。感谢您的帮助!
我有一个名为 delete 的操作项,它获取我创建的 ArrayList 并删除所有选中的联系人(基于我在 class 联系人中的布尔变量)。
当我点击删除时一切都很好,它是一个项目,但如果它超过 6 个项目,onDestroyActionMode 方法会中断我的 onActionItemClicked 方法并且一些项目不会被删除。我该如何解决?
这是我的代码:
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class ContactViewAdapter extends RecyclerView.Adapter<ContactViewAdapter.ContactViewHolder> {
private static final String TAG = "AKS";
private AppCompatActivity mActivity;
private List<Contact> contactList;
public ActionMode mActionMode = null;
public ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.action_mode_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_mode_delete:
for (int i = 0; i < contactList.size(); i++) {
Log.d(TAG, "size " + String.valueOf(contactList.size()));
if (contactList.get(i).isSelected) {
contactList.remove(i);
}
}
notifyDataSetChanged();
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
for (Contact c : contactList) {
c.isSelected = false;
Log.d(TAG, "onDestroyActionMode");
}
mActionMode.finish();
mActionMode = null;
notifyDataSetChanged();
}
};
public class ContactViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public TextView contactName;
public TextView contactMoneyOwed;
public ImageView contactPhoto;
public CheckBox isCheckedBox;
public ContactViewHolder(View v) {
super(v);
contactName = (TextView) itemView.findViewById(R.id.contact_name);
contactMoneyOwed = (TextView) itemView.findViewById(R.id.contact_money_owed);
contactPhoto = (ImageView) itemView.findViewById(R.id.contact_photo);
isCheckedBox = (CheckBox) itemView.findViewById(R.id.listItemCheckBox);
v.setOnClickListener(this);
v.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
boolean everythingIsUnchecked = true;
for (Contact c : contactList) {
if (c.isSelected) {
everythingIsUnchecked = false;
}
}
if (!everythingIsUnchecked) {
isCheckedBox.setChecked(!isCheckedBox.isChecked());
} else {
Toast.makeText(mActivity.getApplicationContext(), "Coming soon!", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onLongClick(View v) {
isCheckedBox.setChecked(true);
return true;
}
}
public ContactViewAdapter(List<Contact> contactList, AppCompatActivity activity) {
this.contactList = contactList;
this.mActivity = activity;
}
@Override
public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ContactViewHolder(v);
}
@Override
public void onBindViewHolder(final ContactViewHolder contactViewHolder, final int position) {
contactViewHolder.contactName.setText(contactList.get(position).name);
contactViewHolder.contactMoneyOwed.setText(contactList.get(position).moneyOwed);
contactViewHolder.contactPhoto.setImageResource(contactList.get(position).photoID);
contactViewHolder.contactPhoto.setOnTouchListener(null);
contactViewHolder.contactPhoto.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
contactViewHolder.isCheckedBox.setChecked(true);
}
return true;
}
});
contactViewHolder.isCheckedBox.setOnCheckedChangeListener(null);
contactViewHolder.isCheckedBox.setChecked(contactList.get(position).isSelected);
if (contactViewHolder.isCheckedBox.isChecked()) {
contactViewHolder.contactPhoto.setVisibility(View.GONE);
contactViewHolder.isCheckedBox.setVisibility(View.VISIBLE);
} else {
contactViewHolder.isCheckedBox.setVisibility(View.GONE);
contactViewHolder.contactPhoto.setVisibility(View.VISIBLE);
}
contactViewHolder.isCheckedBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, String.valueOf(position));
contactList.get(position).isSelected = isChecked;
boolean everythingIsUnchecked = true;
for (Contact c : contactList) {
if (c.isSelected) {
everythingIsUnchecked = false;
}
}
if (mActionMode == null) {
mActionMode = mActivity.startActionMode(mActionModeCallback);
} else if (everythingIsUnchecked) {
mActionMode.finish();
mActionMode = null;
}
if (isChecked) {
contactViewHolder.contactPhoto.setVisibility(View.GONE);
contactViewHolder.isCheckedBox.setVisibility(View.VISIBLE);
} else {
contactViewHolder.isCheckedBox.setVisibility(View.GONE);
contactViewHolder.contactPhoto.setVisibility(View.VISIBLE);
}
}
});
}
@Override
public int getItemCount() {
return contactList.size();
}
}
这是我从日志中得到的:
10-03 19:47:23.181 1962-1962/com.example.andreassavva.expensemanager D/AKS: 0
10-03 19:47:23.413 1962-1962/com.example.andreassavva.expensemanager D/AKS: 1
10-03 19:47:23.789 1962-1962/com.example.andreassavva.expensemanager D/AKS: 2
10-03 19:47:24.067 1962-1962/com.example.andreassavva.expensemanager D/AKS: 3
10-03 19:47:24.453 1962-1962/com.example.andreassavva.expensemanager D/AKS: 4
10-03 19:47:25.115 1962-1962/com.example.andreassavva.expensemanager D/AKS: 5
10-03 19:47:26.350 1962-1962/com.example.andreassavva.expensemanager D/AKS: 6
10-03 19:47:26.734 1962-1962/com.example.andreassavva.expensemanager D/AKS: 7
10-03 19:47:27.046 1962-1962/com.example.andreassavva.expensemanager D/AKS: 8
10-03 19:47:27.468 1962-1962/com.example.andreassavva.expensemanager D/AKS: 9
10-03 19:47:27.812 1962-1962/com.example.andreassavva.expensemanager D/AKS: 10
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 11
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 10
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 9
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 8
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 7
10-03 19:47:29.658 1962-1962/com.example.andreassavva.expensemanager D/AKS: size 6
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
10-03 19:47:29.659 1962-1962/com.example.andreassavva.expensemanager D/AKS: onDestroyActionMode
ActionMode.finish()
呼叫 onDestroyActionMode()
。因此,从 onDestroyActionMode()
实现中删除对 finish()
的调用。新实现变为:
@Override
public void onDestroyActionMode(ActionMode mode) {
for (Contact c : contactList) {
c.isSelected = false;
Log.d(TAG, "onDestroyActionMode");
}
//mActionMode.finish();
mActionMode = null;
notifyDataSetChanged();
}
由于您在 onDestroyActionMode()
中调用 notifyDataSetChanged()
,请从 onActionItemClicked()
的实现中删除该调用。新的 onActionItemClicked()
实现变为:
编辑:
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_mode_delete:
Iterator<Contact> contactIterator = contactList.iterator();
while(contactIterator.hasNext()) {
Contact contact = contactIterator.next();
if (contact.isSelected) {
contactIterator.remove();
}
}
//notifyDataSetChanged();
mode.finish();// This calls 'onDestroyActionMode()'
// and it will notify the data set change.
return true;
default:
return false;
}
}
想通了。我的 for 循环很烂。我需要将其更改为
for (int i = contactList.size() - 1; i >= 0; i--) {
if (contactList.get(i).isSelected()) {
contactList.remove(i);
}
}
相反。感谢您的帮助!