From 7ce74d378fd1078713c599c22750fccdb7acb15f Mon Sep 17 00:00:00 2001 From: orangenbaumblatt Date: Sat, 18 Apr 2020 18:54:37 +0200 Subject: [PATCH] Added selection indicator in icon slot (#344) Changed selection color for black theme Changed indicator color to black secondary Fix indicator flickering when scrolling Applied patch Fix unsharp selection icon Add selection indicators to small and compact view --- .../aegis/ui/views/EntryAdapter.java | 30 +++++++++++------- .../aegis/ui/views/EntryHolder.java | 31 +++++++++++++++++-- .../aegis/ui/views/EntryListView.java | 7 ++++- app/src/main/res/anim/item_scale_in.xml | 11 +++++++ app/src/main/res/anim/item_scale_out.xml | 11 +++++++ app/src/main/res/drawable/item_selected.xml | 12 +++++++ app/src/main/res/layout/card_entry.xml | 22 ++++++++++--- .../main/res/layout/card_entry_compact.xml | 12 +++++++ app/src/main/res/layout/card_entry_small.xml | 12 +++++++ app/src/main/res/values/colors.xml | 2 +- 10 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/anim/item_scale_in.xml create mode 100644 app/src/main/res/anim/item_scale_out.xml create mode 100644 app/src/main/res/drawable/item_selected.xml diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java index 2e92a29b..65e122f4 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java @@ -306,12 +306,12 @@ public class EntryAdapter extends RecyclerView.Adapter implements I @Override public void onBindViewHolder(final EntryHolder holder, int position) { VaultEntry entry = _shownEntries.get(position); - holder.setFocused(_selectedEntries.contains(entry)); boolean hidden = _tapToReveal && entry != _focusedEntry; boolean dimmed = _highlightEntry && _focusedEntry != null && _focusedEntry != entry; boolean showProgress = !isPeriodUniform() && entry.getInfo() instanceof TotpInfo; holder.setData(entry, _showAccountName, showProgress, hidden, dimmed); + holder.setFocused(_selectedEntries.contains(entry)); holder.loadIcon(_view); holder.itemView.setOnClickListener(new View.OnClickListener() { @@ -332,9 +332,9 @@ public class EntryAdapter extends RecyclerView.Adapter implements I if (_selectedEntries.contains(entry)) { _view.onDeselect(entry); removeSelectedEntry(entry); - holder.setFocused(false); + holder.setFocusedAndAnimate(false); } else { - holder.setFocused(true); + holder.setFocusedAndAnimate(true); addSelectedEntry(entry); _view.onSelect(entry); } @@ -351,7 +351,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I public boolean onLongClick(View v) { int position = holder.getAdapterPosition(); if (_selectedEntries.isEmpty()) { - holder.setFocused(true); + holder.setFocusedAndAnimate(true); } return _view.onLongEntryClick(_shownEntries.get(position)); @@ -465,20 +465,26 @@ public class EntryAdapter extends RecyclerView.Adapter implements I } public void addSelectedEntry(VaultEntry entry) { - if (entry == null) { - for (VaultEntry vaultEntry: _selectedEntries) { - notifyItemChanged(_shownEntries.indexOf(vaultEntry)); - } - - _selectedEntries.clear(); - return; - } else if (_highlightEntry) { + if (_highlightEntry) { resetFocus(); } _selectedEntries.add(entry); } + public void deselectAllEntries() { + for (VaultEntry entry: _selectedEntries) { + for (EntryHolder holder : _holders) { + if (holder.getEntry() == entry) { + holder.setFocusedAndAnimate(false); + break; + } + } + } + + _selectedEntries.clear(); + } + public boolean isDragAndDropAllowed() { return _sortCategory == SortCategory.CUSTOM && _groupFilter == null && _searchFilter == null; } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java index 5b9160f4..dc7ac55b 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java @@ -14,7 +14,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.amulyakhare.textdrawable.TextDrawable; import com.beemdevelopment.aegis.R; -import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.helpers.TextDrawableHelper; import com.beemdevelopment.aegis.helpers.ThemeHelper; import com.beemdevelopment.aegis.helpers.UiRefresher; @@ -22,6 +21,7 @@ import com.beemdevelopment.aegis.otp.HotpInfo; import com.beemdevelopment.aegis.otp.OtpInfo; import com.beemdevelopment.aegis.otp.SteamInfo; import com.beemdevelopment.aegis.otp.TotpInfo; +import com.beemdevelopment.aegis.vault.VaultEntry; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; @@ -37,6 +37,9 @@ public class EntryHolder extends RecyclerView.ViewHolder { private VaultEntry _entry; private ImageView _buttonRefresh; private RelativeLayout _description; + + private final ImageView _selected; + private final Handler _selectedHandler; private boolean _hidden; @@ -46,6 +49,9 @@ public class EntryHolder extends RecyclerView.ViewHolder { private UiRefresher _refresher; private Handler _animationHandler; + private Animation _scaleIn; + private Animation _scaleOut; + public EntryHolder(final View view) { super(view); @@ -58,12 +64,17 @@ public class EntryHolder extends RecyclerView.ViewHolder { _description = view.findViewById(R.id.description); _profileDrawable = view.findViewById(R.id.ivTextDrawable); _buttonRefresh = view.findViewById(R.id.buttonRefresh); + _selected = view.findViewById(R.id.ivSelected); + _selectedHandler = new Handler(); _progressBar = view.findViewById(R.id.progressBar); int primaryColorId = view.getContext().getResources().getColor(R.color.colorPrimary); _progressBar.getProgressDrawable().setColorFilter(primaryColorId, PorterDuff.Mode.SRC_IN); _view.setBackground(_view.getContext().getResources().getDrawable(R.color.card_background)); + _scaleIn = AnimationUtils.loadAnimation(view.getContext(), R.anim.item_scale_in); + _scaleOut = AnimationUtils.loadAnimation(view.getContext(), R.anim.item_scale_out); + _refresher = new UiRefresher(new UiRefresher.Listener() { @Override public void onRefresh() { @@ -76,7 +87,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { @Override public long getMillisTillNextRefresh() { - return ((TotpInfo)_entry.getInfo()).getMillisTillNextRotation(); + return ((TotpInfo) _entry.getInfo()).getMillisTillNextRotation(); } }); } @@ -85,6 +96,10 @@ public class EntryHolder extends RecyclerView.ViewHolder { _entry = entry; _hidden = hidden; + _selected.clearAnimation(); + _selected.setVisibility(View.GONE); + _selectedHandler.removeCallbacksAndMessages(null); + // only show the progress bar if there is no uniform period and the entry type is TotpInfo setShowProgress(showProgress); @@ -148,6 +163,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { public void setFocused(boolean focused) { if (focused) { + _selected.setVisibility(View.VISIBLE); _view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackgroundFocused, _view.getContext().getTheme())); } else { _view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackground, _view.getContext().getTheme())); @@ -155,6 +171,17 @@ public class EntryHolder extends RecyclerView.ViewHolder { _view.setSelected(focused); } + public void setFocusedAndAnimate(boolean focused) { + setFocused(focused); + + if (focused) { + _selected.startAnimation(_scaleIn); + } else { + _selected.startAnimation(_scaleOut); + _selectedHandler.postDelayed(() -> _selected.setVisibility(View.GONE), 150); + } + } + public void destroy() { _refresher.destroy(); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java index 5b401193..17c8e8f0 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java @@ -139,7 +139,12 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { public void setActionModeState(boolean enabled, VaultEntry entry) { _touchCallback.setSelectedEntry(entry); _touchCallback.setIsLongPressDragEnabled(enabled && _adapter.isDragAndDropAllowed()); - _adapter.addSelectedEntry(entry); + + if (enabled) { + _adapter.addSelectedEntry(entry); + } else { + _adapter.deselectAllEntries(); + } } public void setSortCategory(SortCategory sortCategory, boolean apply) { diff --git a/app/src/main/res/anim/item_scale_in.xml b/app/src/main/res/anim/item_scale_in.xml new file mode 100644 index 00000000..d3aedbb2 --- /dev/null +++ b/app/src/main/res/anim/item_scale_in.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/item_scale_out.xml b/app/src/main/res/anim/item_scale_out.xml new file mode 100644 index 00000000..4392b737 --- /dev/null +++ b/app/src/main/res/anim/item_scale_out.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/item_selected.xml b/app/src/main/res/drawable/item_selected.xml new file mode 100644 index 00000000..040cdcbe --- /dev/null +++ b/app/src/main/res/drawable/item_selected.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/card_entry.xml b/app/src/main/res/layout/card_entry.xml index 3d6b89c8..8d5b0a4a 100644 --- a/app/src/main/res/layout/card_entry.xml +++ b/app/src/main/res/layout/card_entry.xml @@ -2,11 +2,12 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + #363636 #6B6B6B - #1B1B1B + #363636 #ffffff #a7a7a7 #FF5252