From 0a5124207da73a7ff320dd16a3c0f95f7c97798b Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Tue, 4 Jul 2017 14:31:52 +0200 Subject: [PATCH] Make the RecyclerView searchable --- .../flocke/andotp/EntriesCardAdapter.java | 95 ++++++++++++++++--- .../SimpleItemTouchHelperCallback.java | 14 ++- .../shadowice/flocke/andotp/MainActivity.java | 42 +++++++- app/src/main/res/drawable/ic_search_white.xml | 9 ++ app/src/main/res/menu/menu_main.xml | 7 ++ app/src/main/res/values/strings.xml | 1 + 6 files changed, 148 insertions(+), 20 deletions(-) create mode 100644 app/src/main/res/drawable/ic_search_white.xml diff --git a/app/src/main/java/org/shadowice/flocke/andotp/EntriesCardAdapter.java b/app/src/main/java/org/shadowice/flocke/andotp/EntriesCardAdapter.java index c12552d9..edd2f1de 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/EntriesCardAdapter.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/EntriesCardAdapter.java @@ -35,6 +35,8 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; +import android.widget.Filter; +import android.widget.Filterable; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.LinearLayout; @@ -48,19 +50,27 @@ import java.util.ArrayList; import java.util.Collections; public class EntriesCardAdapter extends RecyclerView.Adapter - implements ItemTouchHelperAdapter { + implements ItemTouchHelperAdapter, Filterable { private Context context; + private EntryFilter filter; private ArrayList entries; + private ArrayList displayedEntries; public ViewHolderEventCallback viewHolderEventCallback; public EntriesCardAdapter(Context context, ArrayList entries) { this.context = context; this.entries = entries; + + displayedEntries = defaultIndices(); } @Override public int getItemCount() { + return displayedEntries.size(); + } + + public int getFullItemCount() { return entries.size(); } @@ -70,11 +80,39 @@ public class EntriesCardAdapter extends RecyclerView.Adapter e) { entries = e; + + displayedEntries.clear(); + displayedEntries = defaultIndices(); + + notifyDataSetChanged(); + } + + public ArrayList defaultIndices() { + ArrayList newIdx = new ArrayList<>(); + for (int i = 0; i < entries.size(); i++) + newIdx.add(i); + + return newIdx; + } + + public int removeIndex(int pos) { + int removed = displayedEntries.remove(pos); + + ArrayList newIdx = new ArrayList<>(); + for (int i = 0; i < displayedEntries.size(); i++) { + int idx = displayedEntries.get(i); + if (idx > removed) + idx -= 1; + newIdx.add(idx); + } + displayedEntries = newIdx; + + return removed; } @Override public void onBindViewHolder(EntryViewHolder entryViewHolder, int i) { - Entry entry = entries.get(i); + Entry entry = entries.get(displayedEntries.get(i)); entryViewHolder.OTPValue.setText(entry.getCurrentOTP()); entryViewHolder.OTPLabel.setText(entry.getLabel()); @@ -104,7 +142,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter toPosition; i--) { - Collections.swap(entries, i, i - 1); - } - } + Collections.swap(entries, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); SettingsHelper.store(context, entries); @@ -141,7 +171,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter newIdx = new ArrayList<>(); + if (constraint != null && constraint.length() != 0){ + for (int i = 0; i < entries.size(); i++) { + if (entries.get(i).getLabel().toLowerCase().contains(constraint.toString().toLowerCase())) { + newIdx.add(i); + } + } + } else { + newIdx = defaultIndices(); + } + + filterResults.count = newIdx.size(); + filterResults.values = newIdx; + + return filterResults; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + displayedEntries = (ArrayList) results.values; + notifyDataSetChanged(); + + } + }; + public class EntryViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder { diff --git a/app/src/main/java/org/shadowice/flocke/andotp/ItemTouchHelper/SimpleItemTouchHelperCallback.java b/app/src/main/java/org/shadowice/flocke/andotp/ItemTouchHelper/SimpleItemTouchHelperCallback.java index c495806c..07e5aa9e 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/ItemTouchHelper/SimpleItemTouchHelperCallback.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/ItemTouchHelper/SimpleItemTouchHelperCallback.java @@ -35,20 +35,30 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { public static final float ALPHA_FULL = 1.0f; + private boolean dragEnabled = true; + private boolean swipeEnabled = true; private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { mAdapter = adapter; } + public void setDragEnabled(boolean newDragState) { + this.dragEnabled = newDragState; + } + + public void setSwipeEnabled(boolean newSwipeState) { + this.swipeEnabled = newSwipeState; + } + @Override public boolean isLongPressDragEnabled() { - return true; + return dragEnabled; } @Override public boolean isItemViewSwipeEnabled() { - return true; + return swipeEnabled; } @Override diff --git a/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java b/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java index ed65756c..09808dd0 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/MainActivity.java @@ -41,9 +41,11 @@ import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.support.v7.widget.helper.ItemTouchHelper; import android.view.Menu; @@ -68,6 +70,7 @@ public class MainActivity extends AppCompatActivity { private ArrayList entries; private EntriesCardAdapter adapter; private FloatingActionButton fab; + private SimpleItemTouchHelperCallback touchHelperCallback; private Handler handler; private Runnable handlerTask; @@ -184,7 +187,6 @@ public class MainActivity extends AppCompatActivity { if (success) { entries = SettingsHelper.load(this); adapter.setEntries(entries); - adapter.notifyDataSetChanged(); Toast.makeText(this, R.string.msg_import_success, Toast.LENGTH_LONG).show(); } else { @@ -301,8 +303,8 @@ public class MainActivity extends AppCompatActivity { adapter = new EntriesCardAdapter(this, entries); recList.setAdapter(adapter); - ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); - ItemTouchHelper touchHelper = new ItemTouchHelper(callback); + touchHelperCallback = new SimpleItemTouchHelperCallback(adapter); + ItemTouchHelper touchHelper = new ItemTouchHelper(touchHelperCallback); touchHelper.attachToRecyclerView(recList); final float durationScale = fixAnimationScale(); @@ -334,7 +336,7 @@ public class MainActivity extends AppCompatActivity { animation.start(); boolean change = false; - for(int i =0;i < adapter.getItemCount(); i++){ + for(int i =0;i < adapter.getFullItemCount(); i++){ boolean item_changed = adapter.getItem(i).updateOTP(); change = change || item_changed; } @@ -403,6 +405,38 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); + + MenuItem searchItem = menu.findItem(R.id.menu_search); + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + adapter.getFilter().filter(newText); + return false; + } + }); + + MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + fab.setVisibility(View.GONE); + touchHelperCallback.setDragEnabled(false); + return true; + } + + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + fab.setVisibility(View.VISIBLE); + touchHelperCallback.setDragEnabled(true); + return true; + } + }); + return true; } diff --git a/app/src/main/res/drawable/ic_search_white.xml b/app/src/main/res/drawable/ic_search_white.xml new file mode 100644 index 00000000..47432c17 --- /dev/null +++ b/app/src/main/res/drawable/ic_search_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 5ec5f721..51689c60 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -1,6 +1,13 @@ + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3dcac20a..4f3a0a43 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,6 +42,7 @@ Storage permissions not granted Animator duration scale + Search animator_warning_displayed