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