Merge pull request #5338 from ByteHamster/live-search

Live results in local search
This commit is contained in:
ByteHamster 2021-08-09 21:50:35 +02:00 committed by GitHub
commit 2d6fff4182
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 174 additions and 230 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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<FeedItem> 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<FeedItem>, List<Feed>> 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<FeedItem> items = FeedSearcher.searchFeedItems(getContext(), query, feed);
List<Feed> feeds = FeedSearcher.searchFeeds(getContext(), query);

View File

@ -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;
}

View File

@ -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<Integer, Integer> 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;
}
}
}

View File

@ -1,51 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
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">
<androidx.appcompat.widget.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/toolbar"/>
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" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:id="@+id/feed_title_chip"
android:layout_marginLeft="10dp"
android:layout_marginRight="0dp"
app:closeIconVisible="true"/>
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" />
<ProgressBar
android:layout_centerInParent="true"
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
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" />
<androidx.recyclerview.widget.RecyclerView
android:layout_below="@id/feed_title_chip"
android:id="@+id/recyclerViewFeeds"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:clipToPadding="false"/>
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" />
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
android:id="@+id/recyclerView"
android:layout_below="@id/recyclerViewFeeds"
android:layout_marginTop="-4dp"
android:paddingTop="12dp"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
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" />
</RelativeLayout>

View File

@ -6,8 +6,7 @@
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
custom:showAsAction="collapseActionView|always"
custom:actionViewClass="androidx.appcompat.widget.SearchView"
custom:showAsAction="always"
android:title="@string/search_label"/>
<item

View File

@ -33,8 +33,7 @@
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
custom:showAsAction="always|collapseActionView"
custom:actionViewClass="androidx.appcompat.widget.SearchView"
custom:showAsAction="always"
android:title="@string/search_label"/>
<item

View File

@ -19,8 +19,7 @@
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
custom:showAsAction="collapseActionView|ifRoom"
custom:actionViewClass="androidx.appcompat.widget.SearchView"
custom:showAsAction="ifRoom"
android:title="@string/search_label"/>
<item

View File

@ -1,15 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
custom:showAsAction="always"
android:title="@string/search_label"/>
<item
android:id="@+id/refresh_item"
android:title="@string/refresh_label"
android:menuCategory="container"
custom:showAsAction="always"
android:icon="@drawable/ic_refresh"/>
<item
android:id="@+id/subscriptions_filter"
android:title="@string/filter"

View File

@ -550,6 +550,7 @@
<!-- Search -->
<string name="search_status_no_results">No results were found</string>
<string name="type_to_search">Type a query to search</string>
<string name="search_label">Search</string>
<string name="no_results_for_query">No results were found for \"%1$s\"</string>