Skip to content

Commit

Permalink
Bottom multi-select (#7093)
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteHamster committed Apr 29, 2024
1 parent c063c59 commit a8dfe6f
Show file tree
Hide file tree
Showing 23 changed files with 294 additions and 222 deletions.
1 change: 0 additions & 1 deletion app/build.gradle
Expand Up @@ -114,7 +114,6 @@ dependencies {
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"

implementation 'com.leinardi.android:speed-dial:3.2.0'
implementation 'com.github.ByteHamster:SearchPreference:v2.5.0'
implementation 'com.github.skydoves:balloon:1.5.3'
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.3'
Expand Down
Expand Up @@ -111,9 +111,11 @@ public final void onBindViewHolder(EpisodeItemViewHolder holder, int pos) {
return false;
});

holder.itemView.setSelected(false);
if (inActionMode()) {
holder.secondaryActionButton.setOnClickListener(null);
if (isSelected(pos)) {
holder.itemView.setSelected(true);
holder.itemView.setBackgroundColor(0x88000000
+ (0xffffff & ThemeUtils.getColorFromAttr(mainActivityRef.get(), R.attr.colorAccent)));
} else {
Expand Down
Expand Up @@ -22,10 +22,10 @@

import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;

import de.danoeh.antennapod.ui.screen.SearchFragment;
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
Expand Down Expand Up @@ -72,7 +72,7 @@ public abstract class EpisodesListFragment extends Fragment
protected EpisodeItemListRecyclerView recyclerView;
protected EpisodeItemListAdapter listAdapter;
protected EmptyViewHandler emptyView;
protected SpeedDialView speedDialView;
protected FloatingSelectMenu floatingSelectMenu;
protected MaterialToolbar toolbar;
protected SwipeRefreshLayout swipeRefreshLayout;
protected SwipeActions swipeActions;
Expand Down Expand Up @@ -200,41 +200,30 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMen
emptyView.updateAdapter(listAdapter);
emptyView.hide();

speedDialView = root.findViewById(R.id.fabSD);
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
@Override
public boolean onMainActionSelected() {
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
if (listAdapter.getSelectedCount() == 0) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
Snackbar.LENGTH_SHORT);
return false;
}

@Override
public void onToggleChanged(boolean open) {
if (open && listAdapter.getSelectedCount() == 0) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
Snackbar.LENGTH_SHORT);
speedDialView.close();
}
}
});
speedDialView.setOnActionSelectedListener(actionItem -> {
int confirmationString = 0;
if (listAdapter.getSelectedItems().size() >= 25 || listAdapter.shouldSelectLazyLoadedItems()) {
// Should ask for confirmation
if (actionItem.getId() == R.id.mark_read_batch) {
if (menuItem.getItemId() == R.id.mark_read_batch) {
confirmationString = R.string.multi_select_mark_played_confirmation;
} else if (actionItem.getId() == R.id.mark_unread_batch) {
} else if (menuItem.getItemId() == R.id.mark_unread_batch) {
confirmationString = R.string.multi_select_mark_unplayed_confirmation;
}
}
if (confirmationString == 0) {
performMultiSelectAction(actionItem.getId());
performMultiSelectAction(menuItem.getItemId());
} else {
new ConfirmationDialog(getActivity(), R.string.multi_select, confirmationString) {
@Override
public void onConfirmButtonPressed(DialogInterface dialog) {
performMultiSelectAction(actionItem.getId());
performMultiSelectAction(menuItem.getItemId());
}
}.createNewDialog().show();
}
Expand Down Expand Up @@ -320,13 +309,17 @@ public void onDestroyView() {

@Override
public void onStartSelectMode() {
speedDialView.setVisibility(View.VISIBLE);
floatingSelectMenu.setVisibility(View.VISIBLE);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(),
(int) getResources().getDimension(R.dimen.floating_select_menu_height));
}

@Override
public void onEndSelectMode() {
speedDialView.close();
speedDialView.setVisibility(View.GONE);
floatingSelectMenu.setVisibility(View.GONE);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(), 0);
}

@Subscribe(threadMode = ThreadMode.MAIN)
Expand Down
Expand Up @@ -48,9 +48,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
emptyView.setIcon(R.drawable.ic_inbox);
emptyView.setTitle(R.string.no_inbox_head_label);
emptyView.setMessage(R.string.no_inbox_label);
speedDialView.removeActionItemById(R.id.mark_unread_batch);
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
speedDialView.removeActionItemById(R.id.delete_batch);
floatingSelectMenu.getMenu().findItem(R.id.mark_unread_batch).setVisible(false);
floatingSelectMenu.getMenu().findItem(R.id.remove_from_queue_batch).setVisible(false);
floatingSelectMenu.getMenu().findItem(R.id.delete_batch).setVisible(false);
return root;
}

Expand Down
Expand Up @@ -23,14 +23,12 @@

import com.google.android.material.chip.Chip;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;

import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
import de.danoeh.antennapod.ui.MenuItemUtils;
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
import de.danoeh.antennapod.event.FeedItemEvent;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
Expand All @@ -46,6 +44,7 @@
import de.danoeh.antennapod.ui.discovery.OnlineSearchFragment;
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
Expand Down Expand Up @@ -82,9 +81,9 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
private List<FeedItem> results;
private Chip chip;
private SearchView searchView;
private FloatingSelectMenu floatingSelectMenu;
private Handler automaticSearchDebouncer;
private long lastQueryChange = 0;
private MultiSelectSpeedDialBinding speedDialBinding;
private boolean isOtherViewInFoucus = false;


Expand Down Expand Up @@ -141,9 +140,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
@Nullable Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.search_fragment, container, false);
setupToolbar(layout.findViewById(R.id.toolbar));
speedDialBinding = MultiSelectSpeedDialBinding.bind(layout);
progressBar = layout.findViewById(R.id.progressBar);
recyclerView = layout.findViewById(R.id.recyclerView);
floatingSelectMenu = layout.findViewById(R.id.floatingSelectMenu);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
registerForContextMenu(recyclerView);
adapter = new EpisodeItemListAdapter((MainActivity) getActivity()) {
Expand Down Expand Up @@ -207,25 +206,14 @@ public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newStat
}
}
});
speedDialBinding.fabSD.setOverlayLayout(speedDialBinding.fabSDOverlay);
speedDialBinding.fabSD.inflate(R.menu.episodes_apply_action_speeddial);
speedDialBinding.fabSD.setOnChangeListener(new SpeedDialView.OnChangeListener() {
@Override
public boolean onMainActionSelected() {
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
if (adapter.getSelectedCount() == 0) {
((MainActivity) getActivity())
.showSnackbarAbovePlayer(R.string.no_items_selected, Snackbar.LENGTH_SHORT);
return false;
}

@Override
public void onToggleChanged(boolean open) {
if (open && adapter.getSelectedCount() == 0) {
((MainActivity) getActivity())
.showSnackbarAbovePlayer(R.string.no_items_selected, Snackbar.LENGTH_SHORT);
speedDialBinding.fabSD.close();
}
}
});
speedDialBinding.fabSD.setOnActionSelectedListener(actionItem -> {
new EpisodeMultiSelectActionHandler((MainActivity) getActivity(), actionItem.getId())
new EpisodeMultiSelectActionHandler((MainActivity) getActivity(), menuItem.getItemId())
.handleAction(adapter.getSelectedItems());
adapter.endSelectMode();
return true;
Expand Down Expand Up @@ -438,16 +426,17 @@ private void searchOnline() {
@Override
public void onStartSelectMode() {
searchViewFocusOff();
speedDialBinding.fabSD.removeActionItemById(R.id.remove_from_inbox_batch);
speedDialBinding.fabSD.removeActionItemById(R.id.remove_from_queue_batch);
speedDialBinding.fabSD.removeActionItemById(R.id.delete_batch);
speedDialBinding.fabSD.setVisibility(View.VISIBLE);
floatingSelectMenu.setVisibility(View.VISIBLE);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(),
(int) getResources().getDimension(R.dimen.floating_select_menu_height));
}

@Override
public void onEndSelectMode() {
speedDialBinding.fabSD.close();
speedDialBinding.fabSD.setVisibility(View.GONE);
floatingSelectMenu.setVisibility(View.GONE);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(), 0);
searchViewFocusOn();
}

Expand Down
Expand Up @@ -13,7 +13,6 @@
import androidx.fragment.app.Fragment;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
Expand All @@ -39,6 +38,7 @@
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
import de.danoeh.antennapod.ui.view.LiftOnScrollListener;
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
import io.reactivex.Observable;
Expand Down Expand Up @@ -71,7 +71,7 @@ public class CompletedDownloadsFragment extends Fragment
private Disposable disposable;
private EmptyViewHandler emptyView;
private boolean displayUpArrow;
private SpeedDialView speedDialView;
private FloatingSelectMenu floatingSelectMenu;
private SwipeActions swipeActions;
private ProgressBar progressBar;
private MaterialToolbar toolbar;
Expand Down Expand Up @@ -107,31 +107,19 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
progressBar = root.findViewById(R.id.progLoading);
progressBar.setVisibility(View.VISIBLE);

speedDialView = root.findViewById(R.id.fabSD);
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
speedDialView.removeActionItemById(R.id.download_batch);
speedDialView.removeActionItemById(R.id.mark_read_batch);
speedDialView.removeActionItemById(R.id.mark_unread_batch);
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
speedDialView.removeActionItemById(R.id.remove_all_inbox_item);
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
@Override
public boolean onMainActionSelected() {
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
floatingSelectMenu.getMenu().findItem(R.id.download_batch).setVisible(false);
floatingSelectMenu.getMenu().findItem(R.id.mark_read_batch).setVisible(false);
floatingSelectMenu.getMenu().findItem(R.id.mark_unread_batch).setVisible(false);
floatingSelectMenu.getMenu().findItem(R.id.remove_from_inbox_batch).setVisible(false);
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
if (adapter.getSelectedCount() == 0) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
Snackbar.LENGTH_SHORT);
return false;
}

@Override
public void onToggleChanged(boolean open) {
if (open && adapter.getSelectedCount() == 0) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
Snackbar.LENGTH_SHORT);
speedDialView.close();
}
}
});
speedDialView.setOnActionSelectedListener(actionItem -> {
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), actionItem.getId())
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), menuItem.getItemId())
.handleAction(adapter.getSelectedItems());
adapter.endSelectMode();
return true;
Expand Down Expand Up @@ -331,14 +319,18 @@ private void loadItems() {
@Override
public void onStartSelectMode() {
swipeActions.detach();
speedDialView.setVisibility(View.VISIBLE);
floatingSelectMenu.setVisibility(View.VISIBLE);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(),
(int) getResources().getDimension(R.dimen.floating_select_menu_height));
}

@Override
public void onEndSelectMode() {
speedDialView.close();
speedDialView.setVisibility(View.GONE);
floatingSelectMenu.setVisibility(View.GONE);
swipeActions.attachTo(recyclerView);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
recyclerView.getPaddingRight(), 0);
}

private class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
Expand Down

0 comments on commit a8dfe6f

Please sign in to comment.