summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java466
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java74
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java64
-rw-r--r--app/src/main/res/layout/episodes_apply_action_fragment.xml59
-rw-r--r--app/src/main/res/layout/multi_select_speed_dial.xml3
-rw-r--r--app/src/main/res/layout/queue_fragment.xml31
-rw-r--r--app/src/main/res/layout/simple_list_fragment.xml44
-rw-r--r--app/src/main/res/menu/downloads.xml7
-rw-r--r--app/src/main/res/menu/episodes_apply_action_options.xml58
-rw-r--r--app/src/main/res/menu/feeditemlist_context.xml12
-rw-r--r--app/src/main/res/menu/queue.xml6
13 files changed, 176 insertions, 665 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
index 117ba3258..0e238eae2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -44,7 +44,7 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
return false;
};
- if (!dragDropEnabled) {
+ if (!dragDropEnabled || inActionMode()) {
holder.dragHandle.setVisibility(View.GONE);
holder.dragHandle.setOnTouchListener(null);
holder.coverHolder.setOnTouchListener(null);
@@ -63,11 +63,17 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
inflater.inflate(R.menu.queue_context, menu);
super.onCreateContextMenu(menu, v, menuInfo);
- final boolean keepSorted = UserPreferences.isQueueKeepSorted();
- if (getItem(0).getId() == getLongPressedItem().getId() || keepSorted) {
+ if (!inActionMode()) {
+ menu.findItem(R.id.multi_select).setVisible(true);
+ final boolean keepSorted = UserPreferences.isQueueKeepSorted();
+ if (getItem(0).getId() == getLongPressedItem().getId() || keepSorted) {
+ menu.findItem(R.id.move_to_top_item).setVisible(false);
+ }
+ if (getItem(getItemCount() - 1).getId() == getLongPressedItem().getId() || keepSorted) {
+ menu.findItem(R.id.move_to_bottom_item).setVisible(false);
+ }
+ } else {
menu.findItem(R.id.move_to_top_item).setVisible(false);
- }
- if (getItem(getItemCount() - 1).getId() == getLongPressedItem().getId() || keepSorted) {
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
deleted file mode 100644
index 508ce74f4..000000000
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ /dev/null
@@ -1,466 +0,0 @@
-package de.danoeh.antennapod.dialog;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import androidx.annotation.IdRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.PluralsRes;
-import androidx.annotation.StringRes;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.Toolbar;
-import androidx.collection.ArrayMap;
-import androidx.fragment.app.Fragment;
-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.core.dialog.DownloadRequestErrorDialogCreator;
-import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.storage.DownloadRequestException;
-import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.FeedItemPermutors;
-import de.danoeh.antennapod.core.util.LongList;
-import de.danoeh.antennapod.model.feed.SortOrder;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
-
- public static final String TAG = "EpisodeActionFragment";
-
- public static final int ACTION_ADD_TO_QUEUE = 1;
- public static final int ACTION_REMOVE_FROM_QUEUE = 2;
- private static final int ACTION_MARK_PLAYED = 4;
- private static final int ACTION_MARK_UNPLAYED = 8;
- public static final int ACTION_DOWNLOAD = 16;
- public static final int ACTION_DELETE = 32;
- public static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
- | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE;
-
- /**
- * Specify an action (defined by #flag) 's UI bindings.
- *
- * Includes: the menu / action item and the actual logic
- */
- private static class ActionBinding {
- int flag;
- @IdRes
- final int actionItemId;
- @NonNull
- final Runnable action;
-
- ActionBinding(int flag, @IdRes int actionItemId, @NonNull Runnable action) {
- this.flag = flag;
- this.actionItemId = actionItemId;
- this.action = action;
- }
- }
-
- private final List<? extends ActionBinding> actionBindings;
- private final Map<Long, FeedItem> idMap = new ArrayMap<>();
- private final List<FeedItem> episodes = new ArrayList<>();
- private int actions;
- private final List<String> titles = new ArrayList<>();
- private final LongList checkedIds = new LongList();
-
- private ListView mListView;
- private ArrayAdapter<String> mAdapter;
- private SpeedDialView mSpeedDialView;
- private Toolbar toolbar;
-
- public EpisodesApplyActionFragment() {
- actionBindings = Arrays.asList(
- new ActionBinding(ACTION_ADD_TO_QUEUE,
- R.id.add_to_queue_batch, this::queueChecked),
- new ActionBinding(ACTION_REMOVE_FROM_QUEUE,
- R.id.remove_from_queue_batch, this::removeFromQueueChecked),
- new ActionBinding(ACTION_MARK_PLAYED,
- R.id.mark_read_batch, this::markedCheckedPlayed),
- new ActionBinding(ACTION_MARK_UNPLAYED,
- R.id.mark_unread_batch, this::markedCheckedUnplayed),
- new ActionBinding(ACTION_DOWNLOAD,
- R.id.download_batch, this::downloadChecked),
- new ActionBinding(ACTION_DELETE,
- R.id.delete_batch, this::deleteChecked)
- );
- }
-
- public static EpisodesApplyActionFragment newInstance(List<FeedItem> items, int actions) {
- EpisodesApplyActionFragment f = new EpisodesApplyActionFragment();
- f.episodes.addAll(items);
- for (FeedItem episode : items) {
- f.idMap.put(episode.getId(), episode);
- }
- f.actions = actions;
- return f;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setRetainInstance(true);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false);
-
- toolbar = view.findViewById(R.id.toolbar);
- toolbar.inflateMenu(R.menu.episodes_apply_action_options);
- toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
- toolbar.setOnMenuItemClickListener(this);
- refreshToolbarState();
-
- mListView = view.findViewById(android.R.id.list);
- mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- mListView.setOnItemClickListener((listView, view1, position, rowId) -> {
- long id = episodes.get(position).getId();
- if (checkedIds.contains(id)) {
- checkedIds.remove(id);
- } else {
- checkedIds.add(id);
- }
- refreshCheckboxes();
- });
- mListView.setOnItemLongClickListener((adapterView, view12, position, id) -> {
- new AlertDialog.Builder(getActivity())
- .setItems(R.array.batch_long_press_options, (dialogInterface, item) -> {
- int direction;
- if (item == 0) {
- direction = -1;
- } else {
- direction = 1;
- }
-
- int currentPosition = position + direction;
- while (currentPosition >= 0 && currentPosition < episodes.size()) {
- long id1 = episodes.get(currentPosition).getId();
- if (!checkedIds.contains(id1)) {
- checkedIds.add(id1);
- }
- currentPosition += direction;
- }
- refreshCheckboxes();
- }).show();
- return true;
- });
-
- titles.clear();
- for (FeedItem episode : episodes) {
- titles.add(episode.getTitle());
- }
-
- mAdapter = new ArrayAdapter<>(getActivity(),
- R.layout.simple_list_item_multiple_choice_on_start, titles);
- mListView.setAdapter(mAdapter);
-
- // Init action UI (via a FAB Speed Dial)
- mSpeedDialView = view.findViewById(R.id.fabSD);
- mSpeedDialView.inflate(R.menu.episodes_apply_action_speeddial);
-
- // show only specified actions, and bind speed dial UIs to the actual logic
- for (ActionBinding binding : actionBindings) {
- if ((actions & binding.flag) == 0) {
- mSpeedDialView.removeActionItemById(binding.actionItemId);
- }
- }
-
- mSpeedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
- @Override
- public boolean onMainActionSelected() {
- return false;
- }
-
- @Override
- public void onToggleChanged(boolean open) {
- if (open && checkedIds.size() == 0) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
- Snackbar.LENGTH_SHORT);
- mSpeedDialView.close();
- }
- }
- });
- mSpeedDialView.setOnActionSelectedListener(actionItem -> {
- ActionBinding selectedBinding = null;
- for (ActionBinding binding : actionBindings) {
- if (actionItem.getId() == binding.actionItemId) {
- selectedBinding = binding;
- break;
- }
- }
- if (selectedBinding != null) {
- selectedBinding.action.run();
- } else {
- Log.e(TAG, "Unrecognized speed dial action item. Do nothing. id=" + actionItem.getId());
- }
- return true;
- });
- refreshCheckboxes();
- return view;
- }
-
- public void refreshToolbarState() {
- MenuItem selectAllItem = toolbar.getMenu().findItem(R.id.select_toggle);
- if (checkedIds.size() == episodes.size()) {
- selectAllItem.setIcon(R.drawable.ic_select_none);
- selectAllItem.setTitle(R.string.deselect_all_label);
- } else {
- selectAllItem.setIcon(R.drawable.ic_select_all);
- selectAllItem.setTitle(R.string.select_all_label);
- }
- }
-
- private static final Map<Integer, SortOrder> menuItemIdToSortOrder;
- static {
- Map<Integer, SortOrder> map = new ArrayMap<>();
- map.put(R.id.sort_title_a_z, SortOrder.EPISODE_TITLE_A_Z);
- map.put(R.id.sort_title_z_a, SortOrder.EPISODE_TITLE_Z_A);
- map.put(R.id.sort_date_new_old, SortOrder.DATE_NEW_OLD);
- map.put(R.id.sort_date_old_new, SortOrder.DATE_OLD_NEW);
- map.put(R.id.sort_duration_long_short, SortOrder.DURATION_LONG_SHORT);
- map.put(R.id.sort_duration_short_long, SortOrder.DURATION_SHORT_LONG);
- menuItemIdToSortOrder = Collections.unmodifiableMap(map);
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- @StringRes int resId = 0;
- switch (item.getItemId()) {
- case R.id.select_options:
- return true;
- case R.id.select_toggle:
- if (checkedIds.size() == episodes.size()) {
- checkNone();
- } else {
- checkAll();
- }
- return true;
- case R.id.check_all:
- checkAll();
- resId = R.string.selected_all_label;
- break;
- case R.id.check_none:
- checkNone();
- resId = R.string.deselected_all_label;
- break;
- case R.id.check_played:
- checkPlayed(true);
- resId = R.string.selected_played_label;
- break;
- case R.id.check_unplayed:
- checkPlayed(false);
- resId = R.string.selected_unplayed_label;
- break;
- case R.id.check_downloaded:
- checkDownloaded(true);
- resId = R.string.selected_downloaded_label;
- break;
- case R.id.check_not_downloaded:
- checkDownloaded(false);
- resId = R.string.selected_not_downloaded_label;
- break;
- case R.id.check_queued:
- checkQueued(true);
- resId = R.string.selected_queued_label;
- break;
- case R.id.check_not_queued:
- checkQueued(false);
- resId = R.string.selected_not_queued_label;
- break;
- case R.id.check_has_media:
- checkWithMedia();
- resId = R.string.selected_has_media_label;
- break;
- default: // handle various sort options
- SortOrder sortOrder = menuItemIdToSortOrder.get(item.getItemId());
- if (sortOrder != null) {
- sort(sortOrder);
- return true;
- }
- }
- if (resId != 0) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(resId, Snackbar.LENGTH_SHORT);
- return true;
- } else {
- return false;
- }
- }
-
- private void sort(@NonNull SortOrder sortOrder) {
- FeedItemPermutors.getPermutor(sortOrder)
- .reorder(episodes);
- refreshTitles();
- refreshCheckboxes();
- }
-
- private void checkAll() {
- for (FeedItem episode : episodes) {
- if (!checkedIds.contains(episode.getId())) {
- checkedIds.add(episode.getId());
- }
- }
- refreshCheckboxes();
- }
-
- private void checkNone() {
- checkedIds.clear();
- refreshCheckboxes();
- }
-
- private void checkPlayed(boolean isPlayed) {
- for (FeedItem episode : episodes) {
- if (episode.isPlayed() == isPlayed) {
- if (!checkedIds.contains(episode.getId())) {
- checkedIds.add(episode.getId());
- }
- } else {
- if (checkedIds.contains(episode.getId())) {
- checkedIds.remove(episode.getId());
- }
- }
- }
- refreshCheckboxes();
- }
-
- private void checkDownloaded(boolean isDownloaded) {
- for (FeedItem episode : episodes) {
- if (episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) {
- if (!checkedIds.contains(episode.getId())) {
- checkedIds.add(episode.getId());
- }
- } else {
- if (checkedIds.contains(episode.getId())) {
- checkedIds.remove(episode.getId());
- }
- }
- }
- refreshCheckboxes();
- }
-
- private void checkQueued(boolean isQueued) {
- for (FeedItem episode : episodes) {
- if (episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) {
- checkedIds.add(episode.getId());
- } else {
- checkedIds.remove(episode.getId());
- }
- }
- refreshCheckboxes();
- }
-
- private void checkWithMedia() {
- for (FeedItem episode : episodes) {
- if (episode.hasMedia()) {
- checkedIds.add(episode.getId());
- } else {
- checkedIds.remove(episode.getId());
- }
- }
- refreshCheckboxes();
- }
-
- private void refreshTitles() {
- titles.clear();
- for (FeedItem episode : episodes) {
- titles.add(episode.getTitle());
- }
- mAdapter.notifyDataSetChanged();
- }
-
- private void refreshCheckboxes() {
- for (int i = 0; i < episodes.size(); i++) {
- FeedItem episode = episodes.get(i);
- boolean checked = checkedIds.contains(episode.getId());
- mListView.setItemChecked(i, checked);
- }
- refreshToolbarState();
- toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label,
- checkedIds.size(), checkedIds.size()));
- }
-
- private void queueChecked() {
- // Check if an episode actually contains any media files before adding it to queue
- LongList toQueue = new LongList(checkedIds.size());
- for (FeedItem episode : episodes) {
- if (checkedIds.contains(episode.getId()) && episode.hasMedia()) {
- toQueue.add(episode.getId());
- }
- }
- DBWriter.addQueueItem(getActivity(), true, toQueue.toArray());
- close(R.plurals.added_to_queue_batch_label, toQueue.size());
- }
-
- private void removeFromQueueChecked() {
- DBWriter.removeQueueItem(getActivity(), true, checkedIds.toArray());
- close(R.plurals.removed_from_queue_batch_label, checkedIds.size());
- }
-
- private void markedCheckedPlayed() {
- DBWriter.markItemPlayed(FeedItem.PLAYED, checkedIds.toArray());
- close(R.plurals.marked_read_batch_label, checkedIds.size());
- }
-
- private void markedCheckedUnplayed() {
- DBWriter.markItemPlayed(FeedItem.UNPLAYED, checkedIds.toArray());
- close(R.plurals.marked_unread_batch_label, checkedIds.size());
- }
-
- private void downloadChecked() {
- // download the check episodes in the same order as they are currently displayed
- List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
- for (FeedItem episode : episodes) {
- if (checkedIds.contains(episode.getId()) && episode.hasMedia() && !episode.getFeed().isLocalFeed()) {
- toDownload.add(episode);
- }
- }
- try {
- DownloadRequester.getInstance().downloadMedia(getActivity(), true, toDownload.toArray(new FeedItem[0]));
- } catch (DownloadRequestException e) {
- e.printStackTrace();
- DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
- }
- close(R.plurals.downloading_batch_label, toDownload.size());
- }
-
- private void deleteChecked() {
- int countHasMedia = 0;
- int countNoMedia = 0;
- for (long id : checkedIds.toArray()) {
- FeedItem episode = idMap.get(id);
- if (episode.hasMedia() && episode.getMedia().isDownloaded()) {
- countHasMedia++;
- DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
- } else {
- countNoMedia++;
- }
- }
- closeMore(R.plurals.deleted_multi_episode_batch_label, countNoMedia, countHasMedia);
- }
-
- private void close(@PluralsRes int msgId, int numItems) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(
- getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG);
- getActivity().getSupportFragmentManager().popBackStack();
- }
-
- private void closeMore(@PluralsRes int msgId, int countNoMedia, int countHasMedia) {
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(
- getResources().getQuantityString(msgId,
- (countHasMedia + countNoMedia),
- (countHasMedia + countNoMedia), countHasMedia),
- Snackbar.LENGTH_LONG);
- getActivity().getSupportFragmentManager().popBackStack();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index 9e3402972..f6a59f158 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.os.Bundle;
import android.util.Log;
+import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -12,6 +13,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
+
+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.adapter.EpisodeItemListAdapter;
@@ -22,13 +27,13 @@ import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
+import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
-import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
@@ -45,13 +50,11 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
-import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_ADD_TO_QUEUE;
-import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DELETE;
-
/**
* Displays all completed downloads and provides a button to delete them.
*/
-public class CompletedDownloadsFragment extends Fragment {
+public class CompletedDownloadsFragment extends Fragment implements
+ EpisodeItemListAdapter.OnEndSelectModeListener {
private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
@@ -64,6 +67,8 @@ public class CompletedDownloadsFragment extends Fragment {
private boolean isUpdatingFeeds = false;
+ private SpeedDialView speedDialView;
+
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
@@ -74,9 +79,39 @@ public class CompletedDownloadsFragment extends Fragment {
recyclerView = root.findViewById(R.id.recyclerView);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
adapter = new CompletedDownloadsListAdapter((MainActivity) getActivity());
+ adapter.setOnEndSelectModeListener(this);
recyclerView.setAdapter(adapter);
progressBar = root.findViewById(R.id.progLoading);
+ speedDialView = root.findViewById(R.id.fabSD);
+ 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.setOnChangeListener(new SpeedDialView.OnChangeListener() {
+ @Override
+ public boolean onMainActionSelected() {
+ 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()), adapter.getSelectedItems())
+ .handleAction(actionItem.getId());
+ onEndSelectMode();
+ adapter.endSelectMode();
+ return true;
+ });
+
addEmptyView();
EventBus.getDefault().register(this);
return root;
@@ -105,17 +140,12 @@ public class CompletedDownloadsFragment extends Fragment {
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
menu.findItem(R.id.clear_logs_item).setVisible(false);
- menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.episode_actions) {
- ((MainActivity) requireActivity())
- .loadChildFragment(EpisodesApplyActionFragment.newInstance(items, ACTION_DELETE | ACTION_ADD_TO_QUEUE));
- return true;
- } else if (item.getItemId() == R.id.refresh_item) {
+ if (item.getItemId() == R.id.refresh_item) {
AutoUpdateManager.runImmediate(requireContext());
return true;
}
@@ -140,6 +170,13 @@ public class CompletedDownloadsFragment extends Fragment {
Log.i(TAG, "Selected item at current position was null, ignoring selection");
return super.onContextItemSelected(item);
}
+ if (item.getItemId() == R.id.multi_select) {
+ speedDialView.setVisibility(View.VISIBLE);
+ }
+ if (adapter.onContextItemSelected(item)) {
+ return true;
+ }
+
return FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), selectedItem);
}
@@ -151,7 +188,6 @@ public class CompletedDownloadsFragment extends Fragment {
emptyView.attachToRecyclerView(recyclerView);
}
-
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(FeedItemEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
@@ -221,6 +257,12 @@ public class CompletedDownloadsFragment extends Fragment {
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
+ @Override
+ public void onEndSelectMode() {
+ speedDialView.close();
+ speedDialView.setVisibility(View.GONE);
+ }
+
private static class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
public CompletedDownloadsListAdapter(MainActivity mainActivity) {
@@ -232,5 +274,13 @@ public class CompletedDownloadsFragment extends Fragment {
DeleteActionButton actionButton = new DeleteActionButton(getItem(pos));
actionButton.configure(holder.secondaryActionButton, holder.secondaryActionIcon, getActivity());
}
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ if (!inActionMode()) {
+ menu.findItem(R.id.multi_select).setVisible(true);
+ }
+ }
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
index 1f6067125..80ab2b719 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -164,7 +164,6 @@ public class DownloadLogFragment extends ListFragment {
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
- menu.findItem(R.id.episode_actions).setVisible(false);
menu.findItem(R.id.clear_logs_item).setVisible(!downloadLog.isEmpty());
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index d309ac253..3db53595d 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -24,8 +24,11 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
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.adapter.EpisodeItemListAdapter;
import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.DownloadEvent;
@@ -35,6 +38,7 @@ import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
+import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@@ -46,7 +50,6 @@ import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.model.feed.SortOrder;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
-import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.EmptyViewHandler;
@@ -63,14 +66,11 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import java.util.Locale;
-import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DELETE;
-import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DOWNLOAD;
-import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_REMOVE_FROM_QUEUE;
-
/**
* Shows all items in the queue.
*/
-public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
+public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickListener,
+ EpisodeItemListAdapter.OnEndSelectModeListener {
public static final String TAG = "QueueFragment";
private static final String KEY_UP_ARROW = "up_arrow";
@@ -93,6 +93,8 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
private ItemTouchHelper itemTouchHelper;
private SharedPreferences prefs;
+ private SpeedDialView speedDialView;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -277,11 +279,6 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
};
conDialog.createNewDialog().show();
return true;
- case R.id.episode_actions:
- ((MainActivity) requireActivity()).loadChildFragment(
- EpisodesApplyActionFragment.newInstance(queue,
- ACTION_DELETE | ACTION_REMOVE_FROM_QUEUE | ACTION_DOWNLOAD));
- return true;
case R.id.queue_sort_episode_title_asc:
setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
return true;
@@ -402,6 +399,15 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
Log.i(TAG, "Selected item no longer exist, ignoring selection");
return super.onContextItemSelected(item);
}
+ if (item.getItemId() == R.id.multi_select) {
+ speedDialView.setVisibility(View.VISIBLE);
+ refreshToolbarState();
+ infoBar.setVisibility(View.GONE);
+ // Do not return: Let adapter handle its actions, too.
+ }
+ if (recyclerAdapter.onContextItemSelected(item)) {
+ return true;
+ }
switch(item.getItemId()) {
case R.id.move_to_top_item:
@@ -419,7 +425,6 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
}
}
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
@@ -538,6 +543,33 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
progLoading = root.findViewById(R.id.progLoading);
progLoading.setVisibility(View.VISIBLE);
+ speedDialView = root.findViewById(R.id.fabSD);
+ speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
+ speedDialView.removeActionItemById(R.id.mark_read_batch);
+ speedDialView.removeActionItemById(R.id.mark_unread_batch);
+ speedDialView.removeActionItemById(R.id.add_to_queue_batch);
+ speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
+ @Override
+ public boolean onMainActionSelected() {
+ return false;
+ }
+
+ @Override
+ public void onToggleChanged(boolean open) {
+ if (open && recyclerAdapter.getSelectedCount() == 0) {
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
+ Snackbar.LENGTH_SHORT);
+ speedDialView.close();
+ }
+ }
+ });
+ speedDialView.setOnActionSelectedListener(actionItem -> {
+ new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), recyclerAdapter.getSelectedItems())
+ .handleAction(actionItem.getId());
+ onEndSelectMode();
+ recyclerAdapter.endSelectMode();
+ return true;
+ });
return root;
}
@@ -552,6 +584,7 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
if (recyclerAdapter == null) {
MainActivity activity = (MainActivity) getActivity();
recyclerAdapter = new QueueRecyclerAdapter(activity, itemTouchHelper);
+ recyclerAdapter.setOnEndSelectModeListener(this);
recyclerView.setAdapter(recyclerAdapter);
emptyView.updateAdapter(recyclerAdapter);
}
@@ -615,4 +648,11 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
}
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
+
+ @Override
+ public void onEndSelectMode() {
+ speedDialView.close();
+ speedDialView.setVisibility(View.GONE);
+ infoBar.setVisibility(View.VISIBLE);
+ }
}
diff --git a/app/src/main/res/layout/episodes_apply_action_fragment.xml b/app/src/main/res/layout/episodes_apply_action_fragment.xml
deleted file mode 100644
index 78827a12a..000000000
--- a/app/src/main/res/layout/episodes_apply_action_fragment.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.appcompat.widget.Toolbar
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?attr/actionBarSize"
- android:theme="?attr/actionBarTheme"
- android:layout_alignParentTop="true"
- app:navigationIcon="?homeAsUpIndicator"
- android:id="@+id/toolbar"/>
-
- <ListView
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/toolbar"
- android:layout_marginTop="0dp" />
-
- <com.leinardi.android.speeddial.SpeedDialOverlayLayout
- android:id="@+id/fabSDOverlay"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:importantForAccessibility="no"
- android:layout_below="@id/toolbar" />
- <!-- The FAB SpeedDial
- 1. MUST be placed at the bottom of the layout xml to ensure it is at the front,
- clickable on Pre-Lollipop devices (that do not support elevation).
- See: https://stackoverflow.com/a/2614402
- 2. ScrollView is needed to ensure the vertical list of speed dials are
- accessible when screen height is small, eg., landscape mode on most phones.
- -->
- <ScrollView
- android:id="@+id/fabSDScrollCtr"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentEnd="true"
- android:layout_alignParentRight="true"
- android:elevation="@dimen/sd_open_elevation"
- tools:ignore="UnusedAttribute" >
-
- <com.leinardi.android.speeddial.SpeedDialView
- android:id="@+id/fabSD"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:sdMainFabClosedSrc="@drawable/ic_fab_edit"
- app:sdOverlayLayout="@id/fabSDOverlay"
- android:layout_marginEnd="16dp"
- android:layout_marginRight="16dp"
- android:layout_marginBottom="16dp"
- android:accessibilityTraversalBefore="@android:id/list"
- android:contentDescription="@string/apply_action" />
- </ScrollView>
-
-</RelativeLayout>
diff --git a/app/src/main/res/layout/multi_select_speed_dial.xml b/app/src/main/res/layout/multi_select_speed_dial.xml
index 159b9a955..0451471bc 100644
--- a/app/src/main/res/layout/multi_select_speed_dial.xml
+++ b/app/src/main/res/layout/multi_select_speed_dial.xml
@@ -21,6 +21,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
android:elevation="@dimen/sd_open_elevation">
<com.leinardi.android.speeddial.SpeedDialView
diff --git a/app/src/main/res/layout/queue_fragment.xml b/app/src/main/res/layout/queue_fragment.xml
index 3bcd4819f..292b1bb45 100644
--- a/app/src/main/res/layout/queue_fragment.xml
+++ b/app/src/main/res/layout/queue_fragment.xml
@@ -1,42 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools">
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true"
- app:title="@string/queue_label"
- android:id="@+id/toolbar"/>
+ app:title="@string/queue_label" />
<TextView
- android:layout_below="@id/toolbar"
android:id="@+id/info_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_below="@id/toolbar"
android:textSize="12sp"
android:layout_marginTop="-8dp"
android:layout_marginLeft="72dp"
android:layout_marginStart="72dp"
android:layout_marginBottom="4dp"
- tools:text="12 Episodes - Time remaining: 12 hours"/>
+ tools:text="12 Episodes - Time remaining: 12 hours" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/info_bar"
- android:background="?android:attr/listDivider"/>
+ android:background="?android:attr/listDivider" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
- android:id="@+id/swipeRefresh"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@id/divider">
+ android:id="@+id/swipeRefresh"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/divider">
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
@@ -54,4 +56,7 @@
android:indeterminateOnly="true"
android:visibility="gone" />
+ <include
+ layout="@layout/multi_select_speed_dial" />
+
</RelativeLayout>
diff --git a/app/src/main/res/layout/simple_list_fragment.xml b/app/src/main/res/layout/simple_list_fragment.xml
index 989566499..6ea3ab54b 100644
--- a/app/src/main/res/layout/simple_list_fragment.xml
+++ b/app/src/main/res/layout/simple_list_fragment.xml
@@ -1,29 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?attr/actionBarSize"
- android:theme="?attr/actionBarTheme"
- android:layout_alignParentTop="true"
- android:id="@+id/toolbar"/>
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?attr/actionBarSize"
+ android:theme="?attr/actionBarTheme"
+ android:layout_alignParentTop="true" />
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingHorizontal="@dimen/additional_horizontal_spacing"
- android:layout_below="@id/toolbar"
- android:id="@+id/recyclerView"/>
+ android:id="@+id/recyclerView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingHorizontal="@dimen/additional_horizontal_spacing"
+ android:layout_below="@id/toolbar" />
<ProgressBar
- android:id="@+id/progLoading"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:indeterminateOnly="true"
- android:visibility="gone"/>
+ android:id="@+id/progLoading"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:indeterminateOnly="true"
+ android:visibility="gone" />
+
+ <include
+ layout="@layout/multi_select_speed_dial" />
</RelativeLayout>
diff --git a/app/src/main/res/menu/downloads.xml b/app/src/main/res/menu/downloads.xml
index 142f251fc..54469a101 100644
--- a/app/src/main/res/menu/downloads.xml
+++ b/app/src/main/res/menu/downloads.xml
@@ -2,13 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
- android:id="@+id/episode_actions"
- android:menuCategory="container"
- android:title="@string/multi_select"
- android:icon="@drawable/ic_check_multiple"
- android:visible="false"
- app:showAsAction="ifRoom" />
- <item
android:id="@+id/clear_logs_item"
android:menuCategory="container"
android:title="@string/clear_history_label"
diff --git a/app/src/main/res/menu/episodes_apply_action_options.xml b/app/src/main/res/menu/episodes_apply_action_options.xml
deleted file mode 100644
index 221ec4d59..000000000
--- a/app/src/main/res/menu/episodes_apply_action_options.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/sort"
- android:icon="@drawable/ic_sort"
- android:title="@string/sort"
- app:showAsAction="always">
- <menu>
- <item android:id="@+id/sort_title_a_z"
- android:title="@string/sort_title_a_z"/>
- <item android:id="@+id/sort_title_z_a"
- android:title="@string/sort_title_z_a"/>
- <item android:id="@+id/sort_date_new_old"
- android:title="@string/sort_date_new_old"/>
- <item android:id="@+id/sort_date_old_new"
- android:title="@string/sort_date_old_new"/>
- <item android:id="@+id/sort_duration_short_long"
- android:title="@string/sort_duration_short_long"/>
- <item android:id="@+id/sort_duration_long_short"
- android:title="@string/sort_duration_long_short"/>
- </menu>
- </item>
-
- <item
- android:id="@+id/select_options"
- android:icon="@drawable/ic_filter"
- android:title="@string/filter"
- app:showAsAction="always">
-
- <menu>
- <item android:id="@+id/check_all"
- android:title="@string/all_label"/>
- <item android:id="@+id/check_none"
- android:title="@string/select_none_label"/>
- <item android:id="@+id/check_played"
- android:title="@string/played_label"/>
- <item android:id="@+id/check_unplayed"
- android:title="@string/unplayed_label"/>
- <item android:id="@+id/check_downloaded"
- android:title="@string/downloaded_label"/>
- <item android:id="@+id/check_not_downloaded"
- android:title="@string/not_downloaded_label"/>
- <item android:id="@+id/check_queued"
- android:title="@string/queued_label"/>
- <item android:id="@+id/check_not_queued"
- android:title="@string/not_queued_label"/>
- <item android:id="@+id/check_has_media"
- android:title="@string/has_media"/>
- </menu>
- </item>
-
- <item
- android:id="@+id/select_toggle"
- android:title="@string/select_all_label"
- app:showAsAction="always"/>
-</menu>
diff --git a/app/src/main/res/menu/feeditemlist_context.xml b/app/src/main/res/menu/feeditemlist_context.xml
index f55afd3f8..27f1af6ca 100644
--- a/app/src/main/res/menu/feeditemlist_context.xml
+++ b/app/src/main/res/menu/feeditemlist_context.xml
@@ -1,12 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:id="@+id/multi_select"
- android:menuCategory="container"
- android:title="@string/multi_select"
- android:visible="false"/>
-
- <item
android:id="@id/skip_episode_item"
android:menuCategory="container"
android:title="@string/skip_episode_label" />
@@ -75,4 +69,10 @@
android:id="@+id/share_item"
android:menuCategory="container"
android:title="@string/share_label" />
+
+ <item
+ android:id="@+id/multi_select"
+ android:menuCategory="container"
+ android:title="@string/multi_select"
+ android:visible="false" />
</menu> \ No newline at end of file
diff --git a/app/src/main/res/menu/queue.xml b/app/src/main/res/menu/queue.xml
index adf44b8b1..34d8f32c0 100644
--- a/app/src/main/res/menu/queue.xml
+++ b/app/src/main/res/menu/queue.xml
@@ -115,10 +115,4 @@
android:title="@string/clear_queue_label"
custom:showAsAction="collapseActionView"
android:icon="@drawable/ic_check"/>
-
- <item
- android:id="@+id/episode_actions"
- custom:showAsAction="collapseActionView"
- android:title="@string/multi_select" />
-
</menu>