Multi-select deletion of apps in settings page

This commit is contained in:
Matthew Wong 2015-08-11 19:56:32 -04:00
parent b75190fcd7
commit f4c0ee607e
4 changed files with 96 additions and 5 deletions

View file

@ -8,7 +8,6 @@ import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@ -149,7 +148,6 @@ public class AutofillPreferenceActivity extends AppCompatActivity {
args.putInt("position", recyclerAdapter.getPosition(packageName));
df.setArguments(args);
df.show(getFragmentManager(), "autofill_dialog");
// TODO if called from dialog 'Settings' button, should activity finish at OK?
}
}

View file

@ -5,8 +5,11 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -15,13 +18,19 @@ import android.widget.TextView;
import com.zeapo.pwdstore.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecyclerAdapter.ViewHolder> {
private ArrayList<ApplicationInfo> apps;
private PackageManager pm;
private AutofillPreferenceActivity activity;
private final Set<Integer> selectedItems;
private ActionMode actionMode;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public View view;
public TextView name;
public TextView secondary;
@ -35,11 +44,30 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
secondary = (TextView) view.findViewById(R.id.secondary_text);
icon = (ImageView) view.findViewById(R.id.app_icon);
view.setOnClickListener(this);
view.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
activity.showDialog(packageName, name.getText().toString());
if (actionMode != null) {
toggleSelection(getAdapterPosition(), view);
if (selectedItems.isEmpty()) {
actionMode.finish();
}
} else {
activity.showDialog(packageName, name.getText().toString());
}
}
@Override
public boolean onLongClick(View v) {
if (actionMode != null) {
return false;
}
toggleSelection(getAdapterPosition(), view);
// Start the CAB using the ActionMode.Callback
actionMode = activity.startSupportActionMode(actionModeCallback);
return true;
}
}
@ -47,6 +75,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
this.apps = apps;
this.pm = pm;
this.activity = activity;
this.selectedItems = new TreeSet<>(Collections.reverseOrder());
}
@Override
@ -80,6 +109,8 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
}
holder.icon.setImageDrawable(pm.getApplicationIcon(app));
holder.packageName = app.packageName;
holder.view.setSelected(selectedItems.contains(position));
}
@Override
@ -105,4 +136,61 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
}
return -1;
}
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.context_pass, 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.menu_delete_password:
// don't ask for confirmation
for (int position : selectedItems) {
remove(position);
}
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
for (Iterator it = selectedItems.iterator(); it.hasNext();) {
// need the setSelected line in onBind
notifyItemChanged((Integer) it.next());
it.remove();
}
actionMode = null;
}
};
public void remove(int position) {
ApplicationInfo applicationInfo = this.apps.get(position);
SharedPreferences prefs
= activity.getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
prefs.edit().remove(applicationInfo.packageName).apply();
this.apps.remove(position);
this.notifyItemRemoved(position);
}
public void toggleSelection(int position, View view) {
if (!selectedItems.remove(position)) {
selectedItems.add(position);
view.setSelected(true);
} else {
view.setSelected(false);
}
}
}

View 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="@color/blue_grey_200" />
<item android:drawable="@color/grey_white_1000" />
</selector>

View file

@ -3,7 +3,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@color/grey_white_1000">
android:background="@drawable/autofill_row_background">
<LinearLayout
android:layout_width="match_parent"