Bottom multi-select (#7093)
This commit is contained in:
parent
c063c59af3
commit
a8dfe6f123
|
@ -114,7 +114,6 @@ dependencies {
|
||||||
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
|
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
|
||||||
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
|
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.ByteHamster:SearchPreference:v2.5.0'
|
||||||
implementation 'com.github.skydoves:balloon:1.5.3'
|
implementation 'com.github.skydoves:balloon:1.5.3'
|
||||||
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.3'
|
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.3'
|
||||||
|
|
|
@ -111,9 +111,11 @@ public class EpisodeItemListAdapter extends SelectableAdapter<EpisodeItemViewHol
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
holder.itemView.setSelected(false);
|
||||||
if (inActionMode()) {
|
if (inActionMode()) {
|
||||||
holder.secondaryActionButton.setOnClickListener(null);
|
holder.secondaryActionButton.setOnClickListener(null);
|
||||||
if (isSelected(pos)) {
|
if (isSelected(pos)) {
|
||||||
|
holder.itemView.setSelected(true);
|
||||||
holder.itemView.setBackgroundColor(0x88000000
|
holder.itemView.setBackgroundColor(0x88000000
|
||||||
+ (0xffffff & ThemeUtils.getColorFromAttr(mainActivityRef.get(), R.attr.colorAccent)));
|
+ (0xffffff & ThemeUtils.getColorFromAttr(mainActivityRef.get(), R.attr.colorAccent)));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,10 +22,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||||
|
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
@ -72,7 +72,7 @@ public abstract class EpisodesListFragment extends Fragment
|
||||||
protected EpisodeItemListRecyclerView recyclerView;
|
protected EpisodeItemListRecyclerView recyclerView;
|
||||||
protected EpisodeItemListAdapter listAdapter;
|
protected EpisodeItemListAdapter listAdapter;
|
||||||
protected EmptyViewHandler emptyView;
|
protected EmptyViewHandler emptyView;
|
||||||
protected SpeedDialView speedDialView;
|
protected FloatingSelectMenu floatingSelectMenu;
|
||||||
protected MaterialToolbar toolbar;
|
protected MaterialToolbar toolbar;
|
||||||
protected SwipeRefreshLayout swipeRefreshLayout;
|
protected SwipeRefreshLayout swipeRefreshLayout;
|
||||||
protected SwipeActions swipeActions;
|
protected SwipeActions swipeActions;
|
||||||
|
@ -200,41 +200,30 @@ public abstract class EpisodesListFragment extends Fragment
|
||||||
emptyView.updateAdapter(listAdapter);
|
emptyView.updateAdapter(listAdapter);
|
||||||
emptyView.hide();
|
emptyView.hide();
|
||||||
|
|
||||||
speedDialView = root.findViewById(R.id.fabSD);
|
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
|
||||||
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
|
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
|
||||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
|
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
if (listAdapter.getSelectedCount() == 0) {
|
||||||
@Override
|
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||||
public boolean onMainActionSelected() {
|
Snackbar.LENGTH_SHORT);
|
||||||
return false;
|
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;
|
int confirmationString = 0;
|
||||||
if (listAdapter.getSelectedItems().size() >= 25 || listAdapter.shouldSelectLazyLoadedItems()) {
|
if (listAdapter.getSelectedItems().size() >= 25 || listAdapter.shouldSelectLazyLoadedItems()) {
|
||||||
// Should ask for confirmation
|
// 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;
|
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;
|
confirmationString = R.string.multi_select_mark_unplayed_confirmation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (confirmationString == 0) {
|
if (confirmationString == 0) {
|
||||||
performMultiSelectAction(actionItem.getId());
|
performMultiSelectAction(menuItem.getItemId());
|
||||||
} else {
|
} else {
|
||||||
new ConfirmationDialog(getActivity(), R.string.multi_select, confirmationString) {
|
new ConfirmationDialog(getActivity(), R.string.multi_select, confirmationString) {
|
||||||
@Override
|
@Override
|
||||||
public void onConfirmButtonPressed(DialogInterface dialog) {
|
public void onConfirmButtonPressed(DialogInterface dialog) {
|
||||||
performMultiSelectAction(actionItem.getId());
|
performMultiSelectAction(menuItem.getItemId());
|
||||||
}
|
}
|
||||||
}.createNewDialog().show();
|
}.createNewDialog().show();
|
||||||
}
|
}
|
||||||
|
@ -320,13 +309,17 @@ public abstract class EpisodesListFragment extends Fragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartSelectMode() {
|
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
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialView.close();
|
floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialView.setVisibility(View.GONE);
|
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
|
||||||
|
recyclerView.getPaddingRight(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
|
|
@ -48,9 +48,9 @@ public class InboxFragment extends EpisodesListFragment {
|
||||||
emptyView.setIcon(R.drawable.ic_inbox);
|
emptyView.setIcon(R.drawable.ic_inbox);
|
||||||
emptyView.setTitle(R.string.no_inbox_head_label);
|
emptyView.setTitle(R.string.no_inbox_head_label);
|
||||||
emptyView.setMessage(R.string.no_inbox_label);
|
emptyView.setMessage(R.string.no_inbox_label);
|
||||||
speedDialView.removeActionItemById(R.id.mark_unread_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.mark_unread_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.remove_from_queue_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.delete_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.delete_batch).setVisible(false);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,12 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.chip.Chip;
|
import com.google.android.material.chip.Chip;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
|
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
|
||||||
import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
|
import de.danoeh.antennapod.ui.screen.subscriptions.HorizontalFeedListAdapter;
|
||||||
import de.danoeh.antennapod.ui.MenuItemUtils;
|
import de.danoeh.antennapod.ui.MenuItemUtils;
|
||||||
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
|
|
||||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||||
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
|
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
|
||||||
|
@ -46,6 +44,7 @@ import de.danoeh.antennapod.ui.appstartintent.OnlineFeedviewActivityStarter;
|
||||||
import de.danoeh.antennapod.ui.discovery.OnlineSearchFragment;
|
import de.danoeh.antennapod.ui.discovery.OnlineSearchFragment;
|
||||||
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
|
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
|
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.view.LiftOnScrollListener;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
|
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
@ -82,9 +81,9 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||||
private List<FeedItem> results;
|
private List<FeedItem> results;
|
||||||
private Chip chip;
|
private Chip chip;
|
||||||
private SearchView searchView;
|
private SearchView searchView;
|
||||||
|
private FloatingSelectMenu floatingSelectMenu;
|
||||||
private Handler automaticSearchDebouncer;
|
private Handler automaticSearchDebouncer;
|
||||||
private long lastQueryChange = 0;
|
private long lastQueryChange = 0;
|
||||||
private MultiSelectSpeedDialBinding speedDialBinding;
|
|
||||||
private boolean isOtherViewInFoucus = false;
|
private boolean isOtherViewInFoucus = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,9 +140,9 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
View layout = inflater.inflate(R.layout.search_fragment, container, false);
|
View layout = inflater.inflate(R.layout.search_fragment, container, false);
|
||||||
setupToolbar(layout.findViewById(R.id.toolbar));
|
setupToolbar(layout.findViewById(R.id.toolbar));
|
||||||
speedDialBinding = MultiSelectSpeedDialBinding.bind(layout);
|
|
||||||
progressBar = layout.findViewById(R.id.progressBar);
|
progressBar = layout.findViewById(R.id.progressBar);
|
||||||
recyclerView = layout.findViewById(R.id.recyclerView);
|
recyclerView = layout.findViewById(R.id.recyclerView);
|
||||||
|
floatingSelectMenu = layout.findViewById(R.id.floatingSelectMenu);
|
||||||
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
|
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
|
||||||
registerForContextMenu(recyclerView);
|
registerForContextMenu(recyclerView);
|
||||||
adapter = new EpisodeItemListAdapter((MainActivity) getActivity()) {
|
adapter = new EpisodeItemListAdapter((MainActivity) getActivity()) {
|
||||||
|
@ -207,25 +206,14 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
speedDialBinding.fabSD.setOverlayLayout(speedDialBinding.fabSDOverlay);
|
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
|
||||||
speedDialBinding.fabSD.inflate(R.menu.episodes_apply_action_speeddial);
|
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialBinding.fabSD.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
if (adapter.getSelectedCount() == 0) {
|
||||||
@Override
|
((MainActivity) getActivity())
|
||||||
public boolean onMainActionSelected() {
|
.showSnackbarAbovePlayer(R.string.no_items_selected, Snackbar.LENGTH_SHORT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
new EpisodeMultiSelectActionHandler((MainActivity) getActivity(), menuItem.getItemId())
|
||||||
@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())
|
|
||||||
.handleAction(adapter.getSelectedItems());
|
.handleAction(adapter.getSelectedItems());
|
||||||
adapter.endSelectMode();
|
adapter.endSelectMode();
|
||||||
return true;
|
return true;
|
||||||
|
@ -438,16 +426,17 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||||
@Override
|
@Override
|
||||||
public void onStartSelectMode() {
|
public void onStartSelectMode() {
|
||||||
searchViewFocusOff();
|
searchViewFocusOff();
|
||||||
speedDialBinding.fabSD.removeActionItemById(R.id.remove_from_inbox_batch);
|
floatingSelectMenu.setVisibility(View.VISIBLE);
|
||||||
speedDialBinding.fabSD.removeActionItemById(R.id.remove_from_queue_batch);
|
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
|
||||||
speedDialBinding.fabSD.removeActionItemById(R.id.delete_batch);
|
recyclerView.getPaddingRight(),
|
||||||
speedDialBinding.fabSD.setVisibility(View.VISIBLE);
|
(int) getResources().getDimension(R.dimen.floating_select_menu_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialBinding.fabSD.close();
|
floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialBinding.fabSD.setVisibility(View.GONE);
|
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
|
||||||
|
recyclerView.getPaddingRight(), 0);
|
||||||
searchViewFocusOn();
|
searchViewFocusOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.MainActivity;
|
import de.danoeh.antennapod.activity.MainActivity;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
|
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListAdapter;
|
||||||
|
@ -39,6 +38,7 @@ import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterfa
|
||||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
|
import de.danoeh.antennapod.ui.view.EmptyViewHandler;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemListRecyclerView;
|
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.view.LiftOnScrollListener;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
|
import de.danoeh.antennapod.ui.episodeslist.EpisodeItemViewHolder;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
@ -71,7 +71,7 @@ public class CompletedDownloadsFragment extends Fragment
|
||||||
private Disposable disposable;
|
private Disposable disposable;
|
||||||
private EmptyViewHandler emptyView;
|
private EmptyViewHandler emptyView;
|
||||||
private boolean displayUpArrow;
|
private boolean displayUpArrow;
|
||||||
private SpeedDialView speedDialView;
|
private FloatingSelectMenu floatingSelectMenu;
|
||||||
private SwipeActions swipeActions;
|
private SwipeActions swipeActions;
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
private MaterialToolbar toolbar;
|
private MaterialToolbar toolbar;
|
||||||
|
@ -107,31 +107,19 @@ public class CompletedDownloadsFragment extends Fragment
|
||||||
progressBar = root.findViewById(R.id.progLoading);
|
progressBar = root.findViewById(R.id.progLoading);
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
speedDialView = root.findViewById(R.id.fabSD);
|
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
|
||||||
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
|
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
|
||||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
|
floatingSelectMenu.getMenu().findItem(R.id.download_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.download_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.mark_read_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.mark_read_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.mark_unread_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.mark_unread_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.remove_from_inbox_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
|
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialView.removeActionItemById(R.id.remove_all_inbox_item);
|
if (adapter.getSelectedCount() == 0) {
|
||||||
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||||
@Override
|
Snackbar.LENGTH_SHORT);
|
||||||
public boolean onMainActionSelected() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), menuItem.getItemId())
|
||||||
@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())
|
|
||||||
.handleAction(adapter.getSelectedItems());
|
.handleAction(adapter.getSelectedItems());
|
||||||
adapter.endSelectMode();
|
adapter.endSelectMode();
|
||||||
return true;
|
return true;
|
||||||
|
@ -331,14 +319,18 @@ public class CompletedDownloadsFragment extends Fragment
|
||||||
@Override
|
@Override
|
||||||
public void onStartSelectMode() {
|
public void onStartSelectMode() {
|
||||||
swipeActions.detach();
|
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
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialView.close();
|
floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialView.setVisibility(View.GONE);
|
|
||||||
swipeActions.attachTo(recyclerView);
|
swipeActions.attachTo(recyclerView);
|
||||||
|
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
|
||||||
|
recyclerView.getPaddingRight(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
|
private class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.ui.CoverLoader;
|
import de.danoeh.antennapod.ui.CoverLoader;
|
||||||
import de.danoeh.antennapod.ui.screen.episode.ItemPagerFragment;
|
import de.danoeh.antennapod.ui.screen.episode.ItemPagerFragment;
|
||||||
|
@ -55,7 +54,6 @@ import de.danoeh.antennapod.ui.common.IntentUtils;
|
||||||
import de.danoeh.antennapod.ui.share.ShareUtils;
|
import de.danoeh.antennapod.ui.share.ShareUtils;
|
||||||
import de.danoeh.antennapod.ui.episodeslist.MoreContentListFooterUtil;
|
import de.danoeh.antennapod.ui.episodeslist.MoreContentListFooterUtil;
|
||||||
import de.danoeh.antennapod.databinding.FeedItemListFragmentBinding;
|
import de.danoeh.antennapod.databinding.FeedItemListFragmentBinding;
|
||||||
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
|
|
||||||
import de.danoeh.antennapod.ui.screen.download.DownloadLogDetailsDialog;
|
import de.danoeh.antennapod.ui.screen.download.DownloadLogDetailsDialog;
|
||||||
import de.danoeh.antennapod.ui.FeedItemFilterDialog;
|
import de.danoeh.antennapod.ui.FeedItemFilterDialog;
|
||||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||||
|
@ -105,7 +103,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
private boolean headerCreated = false;
|
private boolean headerCreated = false;
|
||||||
private Disposable disposable;
|
private Disposable disposable;
|
||||||
private FeedItemListFragmentBinding viewBinding;
|
private FeedItemListFragmentBinding viewBinding;
|
||||||
private MultiSelectSpeedDialBinding speedDialBinding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new ItemlistFragment which shows the Feeditems of a specific
|
* Creates new ItemlistFragment which shows the Feeditems of a specific
|
||||||
|
@ -136,7 +133,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
viewBinding = FeedItemListFragmentBinding.inflate(inflater);
|
viewBinding = FeedItemListFragmentBinding.inflate(inflater);
|
||||||
speedDialBinding = MultiSelectSpeedDialBinding.bind(viewBinding.getRoot());
|
|
||||||
viewBinding.toolbar.inflateMenu(R.menu.feedlist);
|
viewBinding.toolbar.inflateMenu(R.menu.feedlist);
|
||||||
viewBinding.toolbar.setOnMenuItemClickListener(this);
|
viewBinding.toolbar.setOnMenuItemClickListener(this);
|
||||||
viewBinding.toolbar.setOnLongClickListener(v -> {
|
viewBinding.toolbar.setOnLongClickListener(v -> {
|
||||||
|
@ -183,12 +179,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView view, int deltaX, int deltaY) {
|
public void onScrolled(@NonNull RecyclerView view, int deltaX, int deltaY) {
|
||||||
super.onScrolled(view, deltaX, deltaY);
|
super.onScrolled(view, deltaX, deltaY);
|
||||||
boolean hasMorePages = feed != null && feed.isPaged() && feed.getNextPageLink() != null;
|
updateRecyclerPadding();
|
||||||
boolean pageLoaderVisible = viewBinding.recyclerView.isScrolledToBottom() && hasMorePages;
|
|
||||||
nextPageLoader.getRoot().setVisibility(pageLoaderVisible ? View.VISIBLE : View.GONE);
|
|
||||||
viewBinding.recyclerView.setPadding(
|
|
||||||
viewBinding.recyclerView.getPaddingLeft(), 0, viewBinding.recyclerView.getPaddingRight(),
|
|
||||||
pageLoaderVisible ? nextPageLoader.getRoot().getMeasuredHeight() : 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -200,26 +191,14 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
|
|
||||||
loadItems();
|
loadItems();
|
||||||
|
|
||||||
// Init action UI (via a FAB Speed Dial)
|
viewBinding.floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
|
||||||
speedDialBinding.fabSD.setOverlayLayout(speedDialBinding.fabSDOverlay);
|
viewBinding.floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialBinding.fabSD.inflate(R.menu.episodes_apply_action_speeddial);
|
if (adapter.getSelectedCount() == 0) {
|
||||||
speedDialBinding.fabSD.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||||
@Override
|
Snackbar.LENGTH_SHORT);
|
||||||
public boolean onMainActionSelected() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), menuItem.getItemId())
|
||||||
@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())
|
|
||||||
.handleAction(adapter.getSelectedItems());
|
.handleAction(adapter.getSelectedItems());
|
||||||
adapter.endSelectMode();
|
adapter.endSelectMode();
|
||||||
return true;
|
return true;
|
||||||
|
@ -227,6 +206,20 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
return viewBinding.getRoot();
|
return viewBinding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRecyclerPadding() {
|
||||||
|
boolean hasMorePages = feed != null && feed.isPaged() && feed.getNextPageLink() != null;
|
||||||
|
boolean pageLoaderVisible = viewBinding.recyclerView.isScrolledToBottom() && hasMorePages;
|
||||||
|
nextPageLoader.getRoot().setVisibility(pageLoaderVisible ? View.VISIBLE : View.GONE);
|
||||||
|
int paddingBottom = 0;
|
||||||
|
if (adapter.inActionMode()) {
|
||||||
|
paddingBottom = (int) getResources().getDimension(R.dimen.floating_select_menu_height);
|
||||||
|
} else if (pageLoaderVisible) {
|
||||||
|
paddingBottom = nextPageLoader.getRoot().getMeasuredHeight();
|
||||||
|
}
|
||||||
|
viewBinding.recyclerView.setPadding(viewBinding.recyclerView.getPaddingLeft(), 0,
|
||||||
|
viewBinding.recyclerView.getPaddingRight(), paddingBottom);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
@ -406,18 +399,16 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||||
@Override
|
@Override
|
||||||
public void onStartSelectMode() {
|
public void onStartSelectMode() {
|
||||||
swipeActions.detach();
|
swipeActions.detach();
|
||||||
if (feed.isLocalFeed()) {
|
viewBinding.floatingSelectMenu.getMenu().findItem(R.id.download_batch).setVisible(!feed.isLocalFeed());
|
||||||
speedDialBinding.fabSD.removeActionItemById(R.id.download_batch);
|
viewBinding.floatingSelectMenu.setVisibility(View.VISIBLE);
|
||||||
}
|
updateRecyclerPadding();
|
||||||
speedDialBinding.fabSD.removeActionItemById(R.id.remove_all_inbox_item);
|
|
||||||
speedDialBinding.fabSD.setVisibility(View.VISIBLE);
|
|
||||||
updateToolbar();
|
updateToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialBinding.fabSD.close();
|
viewBinding.floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialBinding.fabSD.setVisibility(View.GONE);
|
updateRecyclerPadding();
|
||||||
swipeActions.attachTo(viewBinding.recyclerView);
|
swipeActions.attachTo(viewBinding.recyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||||
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
|
import de.danoeh.antennapod.ui.episodes.PlaybackSpeedUtils;
|
||||||
|
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
@ -94,7 +94,7 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||||
private SwipeActions swipeActions;
|
private SwipeActions swipeActions;
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
|
|
||||||
private SpeedDialView speedDialView;
|
private FloatingSelectMenu floatingSelectMenu;
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -436,30 +436,17 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||||
emptyView.setMessage(R.string.no_items_label);
|
emptyView.setMessage(R.string.no_items_label);
|
||||||
emptyView.updateAdapter(recyclerAdapter);
|
emptyView.updateAdapter(recyclerAdapter);
|
||||||
|
|
||||||
speedDialView = root.findViewById(R.id.fabSD);
|
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
|
||||||
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
|
floatingSelectMenu.inflate(R.menu.episodes_apply_action_speeddial);
|
||||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
|
floatingSelectMenu.getMenu().findItem(R.id.add_to_queue_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.mark_read_batch);
|
floatingSelectMenu.getMenu().findItem(R.id.remove_from_inbox_batch).setVisible(false);
|
||||||
speedDialView.removeActionItemById(R.id.mark_unread_batch);
|
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialView.removeActionItemById(R.id.add_to_queue_batch);
|
if (recyclerAdapter.getSelectedCount() == 0) {
|
||||||
speedDialView.removeActionItemById(R.id.remove_all_inbox_item);
|
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||||
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
Snackbar.LENGTH_SHORT);
|
||||||
@Override
|
|
||||||
public boolean onMainActionSelected() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), menuItem.getItemId())
|
||||||
@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()), actionItem.getId())
|
|
||||||
.handleAction(recyclerAdapter.getSelectedItems());
|
.handleAction(recyclerAdapter.getSelectedItems());
|
||||||
recyclerAdapter.endSelectMode();
|
recyclerAdapter.endSelectMode();
|
||||||
return true;
|
return true;
|
||||||
|
@ -528,15 +515,20 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||||
@Override
|
@Override
|
||||||
public void onStartSelectMode() {
|
public void onStartSelectMode() {
|
||||||
swipeActions.detach();
|
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));
|
||||||
refreshToolbarState();
|
refreshToolbarState();
|
||||||
refreshInfoBar();
|
refreshInfoBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialView.close();
|
floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialView.setVisibility(View.GONE);
|
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
|
||||||
|
recyclerView.getPaddingRight(), 0);
|
||||||
|
infoBar.setVisibility(View.VISIBLE);
|
||||||
swipeActions.attachTo(recyclerView);
|
swipeActions.attachTo(recyclerView);
|
||||||
refreshInfoBar();
|
refreshInfoBar();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.leinardi.android.speeddial.SpeedDialView;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
import de.danoeh.antennapod.ui.screen.AddFeedFragment;
|
||||||
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
import de.danoeh.antennapod.ui.screen.SearchFragment;
|
||||||
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
import de.danoeh.antennapod.net.download.serviceinterface.FeedUpdateManager;
|
||||||
|
import de.danoeh.antennapod.ui.view.FloatingSelectMenu;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
@ -86,7 +86,7 @@ public class SubscriptionFragment extends Fragment
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
|
|
||||||
private FloatingActionButton subscriptionAddButton;
|
private FloatingActionButton subscriptionAddButton;
|
||||||
private SpeedDialView speedDialView;
|
private FloatingSelectMenu floatingSelectMenu;
|
||||||
private RecyclerView.ItemDecoration itemDecoration;
|
private RecyclerView.ItemDecoration itemDecoration;
|
||||||
private List<NavDrawerData.DrawerItem> listItems;
|
private List<NavDrawerData.DrawerItem> listItems;
|
||||||
|
|
||||||
|
@ -168,12 +168,11 @@ public class SubscriptionFragment extends Fragment
|
||||||
swipeRefreshLayout.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance));
|
swipeRefreshLayout.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance));
|
||||||
swipeRefreshLayout.setOnRefreshListener(() -> FeedUpdateManager.getInstance().runOnceOrAsk(requireContext()));
|
swipeRefreshLayout.setOnRefreshListener(() -> FeedUpdateManager.getInstance().runOnceOrAsk(requireContext()));
|
||||||
|
|
||||||
speedDialView = root.findViewById(R.id.fabSD);
|
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
|
||||||
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
|
floatingSelectMenu.inflate(R.menu.nav_feed_action_speeddial);
|
||||||
speedDialView.inflate(R.menu.nav_feed_action_speeddial);
|
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||||
speedDialView.setOnActionSelectedListener(actionItem -> {
|
|
||||||
new FeedMultiSelectActionHandler((MainActivity) getActivity(), subscriptionAdapter.getSelectedItems())
|
new FeedMultiSelectActionHandler((MainActivity) getActivity(), subscriptionAdapter.getSelectedItems())
|
||||||
.handleAction(actionItem.getId());
|
.handleAction(menuItem.getItemId());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -370,8 +369,7 @@ public class SubscriptionFragment extends Fragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndSelectMode() {
|
public void onEndSelectMode() {
|
||||||
speedDialView.close();
|
floatingSelectMenu.setVisibility(View.GONE);
|
||||||
speedDialView.setVisibility(View.GONE);
|
|
||||||
subscriptionAddButton.setVisibility(View.VISIBLE);
|
subscriptionAddButton.setVisibility(View.VISIBLE);
|
||||||
subscriptionAdapter.setItems(listItems);
|
subscriptionAdapter.setItems(listItems);
|
||||||
updateFilterVisibility();
|
updateFilterVisibility();
|
||||||
|
@ -386,7 +384,7 @@ public class SubscriptionFragment extends Fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subscriptionAdapter.setItems(feedsOnly);
|
subscriptionAdapter.setItems(feedsOnly);
|
||||||
speedDialView.setVisibility(View.VISIBLE);
|
floatingSelectMenu.setVisibility(View.VISIBLE);
|
||||||
subscriptionAddButton.setVisibility(View.GONE);
|
subscriptionAddButton.setVisibility(View.GONE);
|
||||||
updateFilterVisibility();
|
updateFilterVisibility();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package de.danoeh.antennapod.ui.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import androidx.annotation.MenuRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.PopupMenu;
|
||||||
|
import com.google.android.material.elevation.SurfaceColors;
|
||||||
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.databinding.FloatingSelectMenuBinding;
|
||||||
|
import de.danoeh.antennapod.databinding.FloatingSelectMenuItemBinding;
|
||||||
|
|
||||||
|
public class FloatingSelectMenu extends FrameLayout {
|
||||||
|
private FloatingSelectMenuBinding viewBinding;
|
||||||
|
private Menu menu;
|
||||||
|
private MenuItem.OnMenuItemClickListener menuItemClickListener;
|
||||||
|
|
||||||
|
public FloatingSelectMenu(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatingSelectMenu(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatingSelectMenu(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup() {
|
||||||
|
viewBinding = FloatingSelectMenuBinding.bind(
|
||||||
|
View.inflate(getContext(), R.layout.floating_select_menu, null));
|
||||||
|
viewBinding.card.setCardBackgroundColor(
|
||||||
|
SurfaceColors.getColorForElevation(getContext(), 8 * getResources().getDisplayMetrics().density));
|
||||||
|
addView(viewBinding.getRoot());
|
||||||
|
setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inflate(@MenuRes int menuRes) {
|
||||||
|
PopupMenu popupMenu = new PopupMenu(getContext(), new View(getContext()));
|
||||||
|
popupMenu.inflate(menuRes);
|
||||||
|
menu = popupMenu.getMenu();
|
||||||
|
updateItemVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateItemVisibility() {
|
||||||
|
viewBinding.selectContainer.removeAllViews();
|
||||||
|
if (menu == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < menu.size(); i++) {
|
||||||
|
MenuItem item = menu.getItem(i);
|
||||||
|
if (!item.isVisible()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FloatingSelectMenuItemBinding itemBinding = FloatingSelectMenuItemBinding.bind(
|
||||||
|
View.inflate(getContext(), R.layout.floating_select_menu_item, null));
|
||||||
|
itemBinding.titleLabel.setText(item.getTitle());
|
||||||
|
itemBinding.icon.setImageDrawable(item.getIcon());
|
||||||
|
itemBinding.getRoot().setOnClickListener(view -> menuItemClickListener.onMenuItemClick(item));
|
||||||
|
viewBinding.selectContainer.addView(itemBinding.getRoot());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Menu getMenu() {
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener listener) {
|
||||||
|
this.menuItemClickListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisibility(int visibility) {
|
||||||
|
if (getVisibility() != View.VISIBLE && visibility == View.VISIBLE) {
|
||||||
|
announceForAccessibility(getContext().getString(R.string.multi_select_started_talkback));
|
||||||
|
}
|
||||||
|
super.setVisibility(visibility);
|
||||||
|
viewBinding.scrollView.scrollTo(0, 0);
|
||||||
|
updateItemVisibility();
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,7 +58,10 @@
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
tools:background="@android:color/holo_red_light" />
|
tools:background="@android:color/holo_red_light" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -76,7 +76,10 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
layout="@layout/more_content_list_footer" />
|
layout="@layout/more_content_list_footer" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/floating_select_menu_height">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:cardCornerRadius="16dp">
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/scrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/selectContainer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingHorizontal="2dp"
|
||||||
|
android:paddingVertical="8dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:importantForAccessibility="no" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@id/titleLabel"
|
||||||
|
android:layout_width="96dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:lines="2"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -84,7 +84,10 @@
|
||||||
android:contentDescription="@string/add_feed_label"
|
android:contentDescription="@string/add_feed_label"
|
||||||
app:srcCompat="@drawable/ic_add" />
|
app:srcCompat="@drawable/ic_add" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<merge
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<com.leinardi.android.speeddial.SpeedDialOverlayLayout
|
|
||||||
android:id="@+id/fabSDOverlay"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:importantForAccessibility="no" />
|
|
||||||
|
|
||||||
<!-- 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_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
|
|
||||||
android:id="@+id/fabSD"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:accessibilityTraversalBefore="@android:id/list"
|
|
||||||
android:contentDescription="@string/apply_action"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:sdMainFabClosedSrc="@drawable/ic_fab_edit"
|
|
||||||
app:sdOverlayLayout="@id/fabSDOverlay" />
|
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</merge>
|
|
|
@ -57,7 +57,10 @@
|
||||||
android:indeterminateOnly="true"
|
android:indeterminateOnly="true"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -61,7 +61,10 @@
|
||||||
android:paddingTop="12dp"
|
android:paddingTop="12dp"
|
||||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing" />
|
android:paddingHorizontal="@dimen/additional_horizontal_spacing" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -36,7 +36,10 @@
|
||||||
android:indeterminateOnly="true"
|
android:indeterminateOnly="true"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<include
|
<de.danoeh.antennapod.ui.view.FloatingSelectMenu
|
||||||
layout="@layout/multi_select_speed_dial" />
|
android:id="@+id/floatingSelectMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
<dimen name="additional_horizontal_spacing">0dp</dimen>
|
<dimen name="additional_horizontal_spacing">0dp</dimen>
|
||||||
<!-- Should match with @dimen/m3_navigation_drawer_layout_corner_size -->
|
<!-- Should match with @dimen/m3_navigation_drawer_layout_corner_size -->
|
||||||
<dimen name="drawer_corner_size">16dp</dimen>
|
<dimen name="drawer_corner_size">16dp</dimen>
|
||||||
|
<dimen name="floating_select_menu_height">112dp</dimen>
|
||||||
</resources>
|
</resources>
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:height="24dp"
|
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="?attr/colorOnPrimary" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
|
||||||
</vector>
|
|
|
@ -194,6 +194,7 @@
|
||||||
<string name="multi_select">Multi select</string>
|
<string name="multi_select">Multi select</string>
|
||||||
<string name="select_all_above">Select all above</string>
|
<string name="select_all_above">Select all above</string>
|
||||||
<string name="select_all_below">Select all below</string>
|
<string name="select_all_below">Select all below</string>
|
||||||
|
<string name="multi_select_started_talkback">Multi select actions shown at the bottom</string>
|
||||||
<string name="filtered_label">Filtered</string>
|
<string name="filtered_label">Filtered</string>
|
||||||
<string name="refresh_failed_msg">Last refresh failed. Tap to view details.</string>
|
<string name="refresh_failed_msg">Last refresh failed. Tap to view details.</string>
|
||||||
<string name="open_podcast">Open podcast</string>
|
<string name="open_podcast">Open podcast</string>
|
||||||
|
@ -699,7 +700,6 @@
|
||||||
<string name="load_next_page_label">Load next page</string>
|
<string name="load_next_page_label">Load next page</string>
|
||||||
<string name="position">Position: %1$s</string>
|
<string name="position">Position: %1$s</string>
|
||||||
<string name="remaining_time">Remaining time: %1$s</string>
|
<string name="remaining_time">Remaining time: %1$s</string>
|
||||||
<string name="apply_action">Apply action</string>
|
|
||||||
<string name="play_chapter">Play chapter</string>
|
<string name="play_chapter">Play chapter</string>
|
||||||
<string name="prev_chapter">Previous chapter</string>
|
<string name="prev_chapter">Previous chapter</string>
|
||||||
<string name="next_chapter">Next chapter</string>
|
<string name="next_chapter">Next chapter</string>
|
||||||
|
|
|
@ -42,12 +42,6 @@
|
||||||
website="https://github.com/google/ExoPlayer"
|
website="https://github.com/google/ExoPlayer"
|
||||||
license="Apache 2.0"
|
license="Apache 2.0"
|
||||||
licenseText="LICENSE_APACHE-2.0.txt" />
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
<library
|
|
||||||
name="Floating Action Button Speed Dial"
|
|
||||||
author="Roberto Leinardi"
|
|
||||||
website="https://github.com/leinardi/FloatingActionButtonSpeedDial"
|
|
||||||
license="Apache 2.0"
|
|
||||||
licenseText="LICENSE_APACHE-2.0.txt" />
|
|
||||||
<library
|
<library
|
||||||
name="fyydlin"
|
name="fyydlin"
|
||||||
author="Martin Fietz"
|
author="Martin Fietz"
|
||||||
|
|
Loading…
Reference in New Issue