Merge pull request #99 from wongma7/master
Multi-select (for password deletion)
This commit is contained in:
commit
97c5c5da95
4 changed files with 98 additions and 17 deletions
|
@ -1,10 +1,11 @@
|
||||||
package com.zeapo.pwdstore.utils;
|
package com.zeapo.pwdstore.utils;
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.support.v7.widget.PopupMenu;
|
import android.support.v7.view.ActionMode;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
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;
|
||||||
|
@ -15,11 +16,15 @@ import com.zeapo.pwdstore.PasswordStore;
|
||||||
import com.zeapo.pwdstore.R;
|
import com.zeapo.pwdstore.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecyclerAdapter.ViewHolder> {
|
public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecyclerAdapter.ViewHolder> {
|
||||||
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 Set<Integer> 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 +49,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 TreeSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new views (invoked by the layout manager)
|
// Create new views (invoked by the layout manager)
|
||||||
|
@ -89,33 +95,75 @@ 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);
|
||||||
|
if (selectedItems.isEmpty()) {
|
||||||
|
mActionMode.finish();
|
||||||
|
}
|
||||||
|
} 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
|
||||||
@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.contains(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 position : selectedItems) {
|
||||||
|
activity.deletePassword(PasswordRecyclerAdapter.this, position);
|
||||||
|
}
|
||||||
|
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,11 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
|
||||||
this.notifyItemRemoved(position);
|
this.notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void toggleSelection(int position) {
|
||||||
|
if (!selectedItems.remove(position)) {
|
||||||
|
selectedItems.add(position);
|
||||||
|
}
|
||||||
|
notifyItemChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
5
app/src/main/res/drawable/password_row_background.xml
Normal file
5
app/src/main/res/drawable/password_row_background.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_selected="true" android:drawable="@drawable/selected_rectangle" />
|
||||||
|
<item android:drawable="@drawable/rectangle" />
|
||||||
|
</selector>
|
21
app/src/main/res/drawable/selected_rectangle.xml
Normal file
21
app/src/main/res/drawable/selected_rectangle.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle"
|
||||||
|
android:dither="true">
|
||||||
|
<corners android:radius="2dp"/>
|
||||||
|
<solid android:color="@color/blue_grey_200" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:bottom="2dp" android:left="1dp" android:right="1dp">
|
||||||
|
<shape android:shape="rectangle" android:dither="true">
|
||||||
|
<corners android:radius="2dp" />
|
||||||
|
<solid android:color="@color/blue_grey_100" />
|
||||||
|
|
||||||
|
<padding android:bottom="2dp" android:left="1dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/rectangle"
|
android:background="@drawable/password_row_background"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:layout_gravity="start|center_vertical">
|
android:layout_gravity="start|center_vertical">
|
||||||
|
|
Loading…
Reference in a new issue