Implement multi-select with actionbar

This commit is contained in:
Matthew Wong 2015-07-01 01:49:02 -04:00
parent 679d7f111e
commit 84b5da3ada

View file

@ -1,10 +1,14 @@
package com.zeapo.pwdstore.utils; package com.zeapo.pwdstore.utils;
import android.graphics.Color; import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.PopupMenu; import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log; import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -20,6 +24,8 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
private final PasswordStore activity; private final PasswordStore activity;
private final ArrayList<PasswordItem> values; private final ArrayList<PasswordItem> values;
private final PasswordFragment.OnFragmentInteractionListener listener; private final PasswordFragment.OnFragmentInteractionListener listener;
private final SparseBooleanArray selectedItems;
private ActionMode mActionMode;
// Provide a reference to the views for each data item // Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and // Complex data items may need more than one view per item, and
@ -44,6 +50,7 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
this.values = values; this.values = values;
this.activity = activity; this.activity = activity;
this.listener = listener; this.listener = listener;
selectedItems = new SparseBooleanArray();
} }
// Create new views (invoked by the layout manager) // Create new views (invoked by the layout manager)
@ -89,33 +96,74 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
holder.view.setOnClickListener(new View.OnClickListener() { holder.view.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
listener.onFragmentInteraction(pass); if (mActionMode != null) {
toggleSelection(holder.position);
} else {
listener.onFragmentInteraction(pass);
}
} }
}); });
holder.view.setOnLongClickListener(new View.OnLongClickListener() { holder.view.setOnLongClickListener(new View.OnLongClickListener() {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
PopupMenu p = new PopupMenu(activity, v); if (mActionMode != null) {
p.getMenuInflater().inflate( return false;
R.menu.context_pass, p.getMenu()); }
p.show(); toggleSelection(holder.position);
p.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { // Start the CAB using the ActionMode.Callback defined above
@Override mActionMode = activity.startSupportActionMode(mActionModeCallback);
public boolean onMenuItemClick(MenuItem menuItem) { return true;
if (menuItem.getItemId() == R.id.menu_delete_password) {
activity.deletePassword(PasswordRecyclerAdapter.this, holder.position);
}
return false;
}
});
return false;
} }
}); });
holder.view.setSelected(selectedItems.get(position));
} }
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
mode.getMenuInflater().inflate(R.menu.context_pass, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete_password:
for (int i = 0; i < selectedItems.size(); i++) {
if (selectedItems.valueAt(i)) {
activity.deletePassword(PasswordRecyclerAdapter.this, selectedItems.keyAt(i));
}
}
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
selectedItems.clear();
mActionMode = null;
notifyDataSetChanged();
}
};
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@Override @Override
public int getItemCount() { public int getItemCount() {
@ -146,4 +194,14 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
this.notifyItemRemoved(position); this.notifyItemRemoved(position);
} }
public void toggleSelection(int pos) {
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
}
else {
selectedItems.put(pos, true);
}
notifyItemChanged(pos);
}
} }