Merge pull request #5338 from ByteHamster/live-search
Live results in local search
This commit is contained in:
commit
2d6fff4182
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user