From 9de72a2cab66e852735dd0c9cb6e1452b00fc250 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 8 Aug 2021 13:32:21 +0200 Subject: Live results in local search --- .../fragment/CompletedDownloadsFragment.java | 2 +- .../antennapod/fragment/DownloadLogFragment.java | 2 +- .../antennapod/fragment/EpisodesFragment.java | 2 - .../antennapod/fragment/EpisodesListFragment.java | 80 ++++++++--------- .../antennapod/fragment/FeedItemlistFragment.java | 13 ++- .../danoeh/antennapod/fragment/QueueFragment.java | 15 +++- .../danoeh/antennapod/fragment/SearchFragment.java | 89 ++++++++++++------- .../antennapod/fragment/SubscriptionFragment.java | 5 +- .../antennapod/menuhandler/MenuItemUtils.java | 99 ---------------------- app/src/main/res/layout/search_fragment.xml | 79 ++++++++--------- app/src/main/res/menu/episodes.xml | 3 +- app/src/main/res/menu/feedlist.xml | 3 +- app/src/main/res/menu/queue.xml | 3 +- app/src/main/res/menu/subscriptions.xml | 8 +- 14 files changed, 173 insertions(+), 230 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java (limited to 'app') 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 f02c1a6ac..74661d240 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -27,6 +27,7 @@ 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.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.core.service.download.DownloadService; @@ -35,7 +36,6 @@ 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.menuhandler.FeedItemMenuHandler; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EmptyViewHandler; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; 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 85bc3facf..ddbf6c078 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -22,6 +22,7 @@ import de.danoeh.antennapod.adapter.DownloadLogAdapter; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloadLogEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.DownloadStatus; @@ -30,7 +31,6 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.download.AutoUpdateManager; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java index 1ca5d524b..cfa226f8f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java @@ -18,7 +18,6 @@ import com.google.android.material.tabs.TabLayoutMediator; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; public class EpisodesFragment extends PagedToolbarFragment { @@ -45,7 +44,6 @@ public class EpisodesFragment extends PagedToolbarFragment { Toolbar toolbar = rootView.findViewById(R.id.toolbar); toolbar.setTitle(R.string.episodes_label); toolbar.inflateMenu(R.menu.episodes); - MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), 0, ""); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java index 59556a340..2b4a6bb47 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -25,6 +25,7 @@ import de.danoeh.antennapod.core.event.FeedListUpdateEvent; 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.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import org.greenrobot.eventbus.EventBus; @@ -47,7 +48,6 @@ 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.menuhandler.FeedItemMenuHandler; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EmptyViewHandler; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -121,46 +121,48 @@ public abstract class EpisodesListFragment extends Fragment { @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (!super.onOptionsItemSelected(item)) { - final int itemId = item.getItemId(); - if (itemId == R.id.refresh_item) { - AutoUpdateManager.runImmediate(requireContext()); - return true; - } else if (itemId == R.id.mark_all_read_item) { - ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(getActivity(), - R.string.mark_all_read_label, - R.string.mark_all_read_confirmation_msg) { - - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - DBWriter.markAllItemsRead(); - ((MainActivity) getActivity()).showSnackbarAbovePlayer( - R.string.mark_all_read_msg, Toast.LENGTH_SHORT); - } - }; - markAllReadConfirmationDialog.createNewDialog().show(); - return true; - } else if (itemId == R.id.remove_all_new_flags_item) { - ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(), - R.string.remove_all_new_flags_label, - R.string.remove_all_new_flags_confirmation_msg) { - - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - DBWriter.removeAllNewFlags(); - ((MainActivity) getActivity()).showSnackbarAbovePlayer( - R.string.removed_all_new_flags_msg, Toast.LENGTH_SHORT); - } - }; - removeAllNewFlagsConfirmationDialog.createNewDialog().show(); - return true; - } - return false; - } else { + if (super.onOptionsItemSelected(item)) { + return true; + } + final int itemId = item.getItemId(); + if (itemId == R.id.refresh_item) { + AutoUpdateManager.runImmediate(requireContext()); + return true; + } else if (itemId == R.id.mark_all_read_item) { + ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(getActivity(), + R.string.mark_all_read_label, + R.string.mark_all_read_confirmation_msg) { + + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + DBWriter.markAllItemsRead(); + ((MainActivity) getActivity()).showSnackbarAbovePlayer( + R.string.mark_all_read_msg, Toast.LENGTH_SHORT); + } + }; + markAllReadConfirmationDialog.createNewDialog().show(); + return true; + } else if (itemId == R.id.remove_all_new_flags_item) { + ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(), + R.string.remove_all_new_flags_label, + R.string.remove_all_new_flags_confirmation_msg) { + + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + DBWriter.removeAllNewFlags(); + ((MainActivity) getActivity()).showSnackbarAbovePlayer( + R.string.removed_all_new_flags_msg, Toast.LENGTH_SHORT); + } + }; + removeAllNewFlagsConfirmationDialog.createNewDialog().show(); + return true; + } else if (itemId == R.id.action_search) { + ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance()); return true; } + return false; } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index 9c5f5079d..bea95cb0e 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -37,6 +37,7 @@ import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconTextView; import com.leinardi.android.speeddial.SpeedDialView; +import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; import org.apache.commons.lang3.Validate; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -77,7 +78,6 @@ import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedItemFilter; @@ -115,7 +115,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem private ImageButton butShowSettings; private View header; private Toolbar toolbar; - private ToolbarIconTintManager iconTintManager; private SpeedDialView speedDialView; private boolean displayUpArrow; @@ -184,7 +183,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem AppBarLayout appBar = root.findViewById(R.id.appBar); CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar); - iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) { + ToolbarIconTintManager iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) { @Override protected void doTint(Context themedContext) { toolbar.getMenu().findItem(R.id.sort_items) @@ -294,8 +293,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem if (feed == null) { return; } - MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), feedID, feed.getTitle()); - toolbar.getMenu().findItem(R.id.share_link_item).setVisible(feed.getLink() != null); toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed.getLink() != null); @@ -313,9 +310,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem @Override public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == R.id.action_search) { - item.getActionView().post(() -> iconTintManager.updateTint()); - } if (feed == null) { ((MainActivity) getActivity()).showSnackbarAbovePlayer( R.string.please_wait_for_data, Toast.LENGTH_LONG); @@ -340,6 +334,9 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem RemoveFeedDialog.show(getContext(), feed, () -> ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null)); return true; + } else if (itemId == R.id.action_search) { + ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance(feed.getId(), feed.getTitle())); + return true; } return false; } 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 6f8b9adbb..188731573 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -38,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.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler; import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; import de.danoeh.antennapod.model.feed.FeedItem; @@ -53,7 +54,6 @@ import de.danoeh.antennapod.model.feed.FeedItemFilter; import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.core.util.download.AutoUpdateManager; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EmptyViewHandler; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; @@ -247,7 +247,14 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); private void refreshToolbarState() { - MenuItemUtils.refreshLockItem(getActivity(), toolbar.getMenu()); + final MenuItem queueLock = toolbar.getMenu().findItem(R.id.queue_lock); + if (UserPreferences.isQueueLocked()) { + queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue); + queueLock.setIcon(R.drawable.ic_lock_open); + } else { + queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue); + queueLock.setIcon(R.drawable.ic_lock_closed); + } boolean keepSorted = UserPreferences.isQueueKeepSorted(); toolbar.getMenu().findItem(R.id.queue_sort_random).setVisible(!keepSorted); @@ -326,6 +333,9 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi } refreshToolbarState(); return true; + } else if (itemId == R.id.action_search) { + ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance()); + return true; } return false; } @@ -430,7 +440,6 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi } ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); toolbar.inflateMenu(R.menu.queue); - MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), 0, ""); refreshToolbarState(); infoBar = root.findViewById(R.id.info_bar); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index 855078d03..f8326d9c1 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -1,6 +1,8 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; @@ -55,6 +57,7 @@ public class SearchFragment extends Fragment { private static final String ARG_QUERY = "query"; private static final String ARG_FEED = "feed"; private static final String ARG_FEED_NAME = "feedName"; + private static final int SEARCH_DEBOUNCE_INTERVAL = 1500; private EpisodeItemListAdapter adapter; private FeedSearchResultAdapter adapterFeeds; @@ -64,27 +67,35 @@ public class SearchFragment extends Fragment { private EpisodeItemListRecyclerView recyclerView; private List results; private Chip chip; + private SearchView searchView; + private Handler automaticSearchDebouncer; + private long lastQueryChange = 0; /** * Create a new SearchFragment that searches all feeds. */ - public static SearchFragment newInstance(String query) { - if (query == null) { - query = ""; - } + public static SearchFragment newInstance() { SearchFragment fragment = new SearchFragment(); Bundle args = new Bundle(); - args.putString(ARG_QUERY, query); args.putLong(ARG_FEED, 0); fragment.setArguments(args); return fragment; } + /** + * Create a new SearchFragment that searches all feeds with pre-defined query. + */ + public static SearchFragment newInstance(String query) { + SearchFragment fragment = newInstance(); + fragment.getArguments().putString(ARG_QUERY, query); + return fragment; + } + /** * Create a new SearchFragment that searches one specific feed. */ - public static SearchFragment newInstance(String query, long feed, String feedTitle) { - SearchFragment fragment = newInstance(query); + public static SearchFragment newInstance(long feed, String feedTitle) { + SearchFragment fragment = newInstance(); fragment.getArguments().putLong(ARG_FEED, feed); fragment.getArguments().putString(ARG_FEED_NAME, feedTitle); return fragment; @@ -94,12 +105,7 @@ public class SearchFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - } - - @Override - public void onStart() { - super.onStart(); - search(); + automaticSearchDebouncer = new Handler(Looper.getMainLooper()); } @Override @@ -134,13 +140,19 @@ public class SearchFragment extends Fragment { emptyViewHandler.attachToRecyclerView(recyclerView); emptyViewHandler.setIcon(R.drawable.ic_search); emptyViewHandler.setTitle(R.string.search_status_no_results); + emptyViewHandler.setMessage(R.string.type_to_search); EventBus.getDefault().register(this); chip = layout.findViewById(R.id.feed_title_chip); chip.setOnCloseIconClickListener(v -> { getArguments().putLong(ARG_FEED, 0); - search(); + searchWithProgressBar(); }); + chip.setVisibility((getArguments().getLong(ARG_FEED, 0) == 0) ? View.GONE : View.VISIBLE); + chip.setText(getArguments().getString(ARG_FEED_NAME, "")); + if (getArguments().getString(ARG_QUERY, null) != null) { + search(); + } return layout; } @@ -157,21 +169,30 @@ public class SearchFragment extends Fragment { MenuItem item = toolbar.getMenu().findItem(R.id.action_search); item.expandActionView(); - final SearchView sv = (SearchView) item.getActionView(); - sv.setQueryHint(getString(R.string.search_label)); - sv.clearFocus(); - sv.setQuery(getArguments().getString(ARG_QUERY), false); - sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + searchView = (SearchView) item.getActionView(); + searchView.setQueryHint(getString(R.string.search_label)); + searchView.requestFocus(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { - sv.clearFocus(); - getArguments().putString(ARG_QUERY, s); - search(); + searchView.clearFocus(); + searchWithProgressBar(); return true; } @Override public boolean onQueryTextChange(String s) { + automaticSearchDebouncer.removeCallbacksAndMessages(null); + if (s.isEmpty() || s.endsWith(" ") || (lastQueryChange != 0 + && System.currentTimeMillis() > lastQueryChange + SEARCH_DEBOUNCE_INTERVAL)) { + search(); + } else { + automaticSearchDebouncer.postDelayed(() -> { + search(); + lastQueryChange = 0; // Don't search instantly with first symbol after some pause + }, SEARCH_DEBOUNCE_INTERVAL / 2); + } + lastQueryChange = System.currentTimeMillis(); return false; } }); @@ -256,12 +277,17 @@ public class SearchFragment extends Fragment { search(); } + private void searchWithProgressBar() { + progressBar.setVisibility(View.VISIBLE); + emptyViewHandler.hide(); + search(); + } + private void search() { if (disposable != null) { disposable.dispose(); } - progressBar.setVisibility(View.VISIBLE); - emptyViewHandler.hide(); + chip.setVisibility((getArguments().getLong(ARG_FEED, 0) == 0) ? View.GONE : View.VISIBLE); disposable = Observable.fromCallable(this::performSearch) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -271,19 +297,24 @@ public class SearchFragment extends Fragment { adapter.updateItems(results.first); if (getArguments().getLong(ARG_FEED, 0) == 0) { adapterFeeds.updateData(results.second); - chip.setVisibility(View.GONE); } else { adapterFeeds.updateData(Collections.emptyList()); - chip.setText(getArguments().getString(ARG_FEED_NAME, "")); } - String query = getArguments().getString(ARG_QUERY); - emptyViewHandler.setMessage(getString(R.string.no_results_for_query, query)); + + if (searchView.getQuery().toString().isEmpty()) { + emptyViewHandler.setMessage(R.string.type_to_search); + } else { + emptyViewHandler.setMessage(getString(R.string.no_results_for_query, searchView.getQuery())); + } }, error -> Log.e(TAG, Log.getStackTraceString(error))); } @NonNull private Pair, List> performSearch() { - String query = getArguments().getString(ARG_QUERY); + String query = searchView.getQuery().toString(); + if (query.isEmpty()) { + return new Pair<>(Collections.emptyList(), Collections.emptyList()); + } long feed = getArguments().getLong(ARG_FEED); List items = FeedSearcher.searchFeedItems(getContext(), query, feed); List feeds = FeedSearcher.searchFeeds(getContext(), query); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 23341ff66..a460acbc0 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -39,6 +39,7 @@ import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; +import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadService; @@ -51,7 +52,6 @@ import de.danoeh.antennapod.dialog.RemoveFeedDialog; import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog; import de.danoeh.antennapod.dialog.FeedSortDialog; import de.danoeh.antennapod.dialog.RenameFeedDialog; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EmptyViewHandler; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -194,6 +194,9 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem } else if (itemId == R.id.subscription_num_columns_5) { setColumnNumber(5); return true; + } else if (itemId == R.id.action_search) { + ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance()); + return true; } return false; } diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java deleted file mode 100644 index b42244160..000000000 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java +++ /dev/null @@ -1,99 +0,0 @@ -package de.danoeh.antennapod.menuhandler; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.view.Menu; -import android.view.MenuItem; -import androidx.appcompat.view.menu.MenuItemImpl; -import androidx.appcompat.widget.SearchView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.ui.common.ThemeUtils; -import de.danoeh.antennapod.fragment.SearchFragment; - -import java.util.HashMap; -import java.util.Map; - -/** - * Utilities for menu items. - */ -public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuItemUtils { - - public static void refreshLockItem(Context context, Menu menu) { - final MenuItem queueLock = menu.findItem(R.id.queue_lock); - if (UserPreferences.isQueueLocked()) { - queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue); - queueLock.setIcon(R.drawable.ic_lock_open); - } else { - queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue); - queueLock.setIcon(R.drawable.ic_lock_closed); - } - } - - public static void setupSearchItem(Menu menu, MainActivity activity, long feedId, String feedTitle) { - MenuItem searchItem = menu.findItem(R.id.action_search); - final SearchView sv = (SearchView) searchItem.getActionView(); - sv.setBackgroundColor(ThemeUtils.getColorFromAttr(activity, android.R.attr.windowBackground)); - sv.setQueryHint(activity.getString(R.string.search_label)); - sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String s) { - sv.clearFocus(); - activity.loadChildFragment(SearchFragment.newInstance(s, feedId, feedTitle)); - searchItem.collapseActionView(); - return true; - } - - @Override - public boolean onQueryTextChange(String s) { - return false; - } - }); - searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { - private final Map oldShowAsActionState = new HashMap<>(); - - @Override - public boolean onMenuItemActionExpand(MenuItem clickedItem) { - oldShowAsActionState.clear(); - for (int i = 0; i < menu.size(); i++) { - MenuItem item = menu.getItem(i); - if (item.getItemId() != searchItem.getItemId()) { - oldShowAsActionState.put(item.getItemId(), getShowAsActionFlag(item)); - item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - } - } - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem collapsedItem) { - for (int i = 0; i < menu.size(); i++) { - MenuItem item = menu.getItem(i); - if (item.getItemId() != searchItem.getItemId() - && oldShowAsActionState.containsKey(item.getItemId())) { - item.setShowAsAction(oldShowAsActionState.get(item.getItemId())); - } - } - return true; - } - }); - } - - @SuppressLint("RestrictedApi") - private static int getShowAsActionFlag(MenuItem item) { - if (!(item instanceof MenuItemImpl)) { - return MenuItemImpl.SHOW_AS_ACTION_NEVER; - } - MenuItemImpl itemImpl = ((MenuItemImpl) item); - if (itemImpl.requiresActionButton()) { - return MenuItemImpl.SHOW_AS_ACTION_ALWAYS; - } else if (itemImpl.requestsActionButton()) { - return MenuItemImpl.SHOW_AS_ACTION_IF_ROOM; - } else if (itemImpl.showsTextAsAction()) { - return MenuItemImpl.SHOW_AS_ACTION_WITH_TEXT; - } else { - return MenuItemImpl.SHOW_AS_ACTION_NEVER; - } - } -} diff --git a/app/src/main/res/layout/search_fragment.xml b/app/src/main/res/layout/search_fragment.xml index 28d4778f7..5745cf655 100644 --- a/app/src/main/res/layout/search_fragment.xml +++ b/app/src/main/res/layout/search_fragment.xml @@ -1,51 +1,54 @@ + 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="match_parent"> + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?attr/actionBarSize" + android:theme="?attr/actionBarTheme" + app:navigationIcon="?homeAsUpIndicator" + app:title="@string/search_label" /> + android:id="@+id/feed_title_chip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@id/toolbar" + android:layout_marginLeft="10dp" + android:layout_marginRight="0dp" + android:visibility="gone" + app:closeIconVisible="true" /> + android:id="@+id/progressBar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerInParent="true" + android:layout_gravity="center" + android:visibility="gone" + style="?android:attr/progressBarStyle" /> + android:id="@+id/recyclerViewFeeds" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/feed_title_chip" + android:paddingLeft="12dp" + android:paddingRight="12dp" + android:clipToPadding="false" /> + android:id="@+id/recyclerView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_below="@id/recyclerViewFeeds" + android:layout_marginTop="-4dp" + android:paddingTop="12dp" + android:paddingHorizontal="@dimen/additional_horizontal_spacing" /> + diff --git a/app/src/main/res/menu/episodes.xml b/app/src/main/res/menu/episodes.xml index 22121c905..7a311aedb 100644 --- a/app/src/main/res/menu/episodes.xml +++ b/app/src/main/res/menu/episodes.xml @@ -6,8 +6,7 @@ - + - -