Merge pull request #4625 from ByteHamster/toolbar-rework

Toolbar rework
This commit is contained in:
ByteHamster 2020-11-01 17:20:11 +01:00 committed by GitHub
commit b3c69f1a20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 484 additions and 593 deletions

View File

@ -24,7 +24,10 @@ import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo; import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.contrib.ActivityResultMatchers.hasResultCode; import static androidx.test.espresso.contrib.ActivityResultMatchers.hasResultCode;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot; import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText; import static androidx.test.espresso.matcher.ViewMatchers.withText;
@ -32,7 +35,7 @@ import static de.test.antennapod.EspressoTestUtils.clickPreference;
import static de.test.antennapod.EspressoTestUtils.openNavDrawer; import static de.test.antennapod.EspressoTestUtils.openNavDrawer;
import static de.test.antennapod.EspressoTestUtils.waitForView; import static de.test.antennapod.EspressoTestUtils.waitForView;
import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals; import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
/** /**
@ -80,10 +83,6 @@ public class MainActivityTest {
onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000)); onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000));
} }
private String getActionbarTitle() {
return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString();
}
@Test @Test
public void testBackButtonBehaviorGoToPage() { public void testBackButtonBehaviorGoToPage() {
openNavDrawer(); openNavDrawer();
@ -98,7 +97,8 @@ public class MainActivityTest {
solo.goBackToActivity(MainActivity.class.getSimpleName()); solo.goBackToActivity(MainActivity.class.getSimpleName());
solo.goBack(); solo.goBack();
solo.goBack(); solo.goBack();
assertEquals(solo.getString(R.string.subscriptions_label), getActionbarTitle()); onView(allOf(withId(R.id.toolbar), isDisplayed())).check(
matches(hasDescendant(withText(R.string.subscriptions_label))));
solo.goBack(); solo.goBack();
assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED)); assertThat(mActivityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));
} }

View File

@ -5,7 +5,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -13,7 +12,6 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -114,15 +112,6 @@ public class MainActivity extends CastEnabledActivity {
setNavDrawerSize(); setNavDrawerSize();
final FragmentManager fm = getSupportFragmentManager(); final FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(() -> {
boolean showArrow = fm.getBackStackEntryCount() != 0;
if (drawerToggle != null) { // Tablet layout does not have a drawer
drawerToggle.setDrawerIndicatorEnabled(!showArrow);
} else if (getActionBar() != null) {
getActionBar().setDisplayHomeAsUpEnabled(showArrow);
}
});
if (fm.findFragmentByTag(MAIN_FRAGMENT_TAG) == null) { if (fm.findFragmentByTag(MAIN_FRAGMENT_TAG) == null) {
String lastFragment = NavDrawerFragment.getLastNavFragment(this); String lastFragment = NavDrawerFragment.getLastNavFragment(this);
if (ArrayUtils.contains(NavDrawerFragment.NAV_DRAWER_TAGS, lastFragment)) { if (ArrayUtils.contains(NavDrawerFragment.NAV_DRAWER_TAGS, lastFragment)) {
@ -194,8 +183,7 @@ public class MainActivity extends CastEnabledActivity {
} }
}; };
@Override public void setupToolbarToggle(@Nullable Toolbar toolbar) {
public void setSupportActionBar(@Nullable Toolbar toolbar) {
if (drawerLayout != null) { // Tablet layout does not have a drawer if (drawerLayout != null) { // Tablet layout does not have a drawer
drawerLayout.removeDrawerListener(drawerToggle); drawerLayout.removeDrawerListener(drawerToggle);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
@ -203,12 +191,13 @@ public class MainActivity extends CastEnabledActivity {
drawerLayout.addDrawerListener(drawerToggle); drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState(); drawerToggle.syncState();
drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0); drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
drawerToggle.setToolbarNavigationClickListener(v -> getSupportFragmentManager().popBackStack());
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) { } else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
toolbar.setNavigationIcon(null); toolbar.setNavigationIcon(null);
} else { } else {
toolbar.setNavigationIcon(ThemeUtils.getDrawableFromAttr(this, R.attr.homeAsUpIndicator)); toolbar.setNavigationIcon(ThemeUtils.getDrawableFromAttr(this, R.attr.homeAsUpIndicator));
toolbar.setNavigationOnClickListener(v -> getSupportFragmentManager().popBackStack());
} }
super.setSupportActionBar(toolbar);
} }
private void checkFirstLaunch() { private void checkFirstLaunch() {

View File

@ -1,12 +1,8 @@
package de.danoeh.antennapod.dialog; package de.danoeh.antennapod.dialog;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -17,10 +13,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.PluralsRes; import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.collection.ArrayMap; import androidx.collection.ArrayMap;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView; import com.leinardi.android.speeddial.SpeedDialView;
@ -34,6 +28,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemPermutors; import de.danoeh.antennapod.core.util.FeedItemPermutors;
import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.SortOrder; import de.danoeh.antennapod.core.util.SortOrder;
import de.danoeh.antennapod.core.util.ThemeUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -41,7 +36,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class EpisodesApplyActionFragment extends Fragment { public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
public static final String TAG = "EpisodeActionFragment"; public static final String TAG = "EpisodeActionFragment";
@ -53,7 +48,6 @@ public class EpisodesApplyActionFragment extends Fragment {
public static final int ACTION_DELETE = 32; public static final int ACTION_DELETE = 32;
public static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE public static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
| ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE; | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE;
private Toolbar toolbar;
/** /**
* Specify an action (defined by #flag) 's UI bindings. * Specify an action (defined by #flag) 's UI bindings.
@ -84,7 +78,7 @@ public class EpisodesApplyActionFragment extends Fragment {
private ListView mListView; private ListView mListView;
private ArrayAdapter<String> mAdapter; private ArrayAdapter<String> mAdapter;
private SpeedDialView mSpeedDialView; private SpeedDialView mSpeedDialView;
private MenuItem mSelectToggle; private Toolbar toolbar;
public EpisodesApplyActionFragment() { public EpisodesApplyActionFragment() {
actionBindings = Arrays.asList( actionBindings = Arrays.asList(
@ -117,7 +111,6 @@ public class EpisodesApplyActionFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
} }
@Override @Override
@ -125,6 +118,12 @@ public class EpisodesApplyActionFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false); View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false);
toolbar = view.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.episodes_apply_action_options);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
toolbar.setOnMenuItemClickListener(this);
refreshToolbarState();
mListView = view.findViewById(android.R.id.list); mListView = view.findViewById(android.R.id.list);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mListView.setOnItemClickListener((listView, view1, position, rowId) -> { mListView.setOnItemClickListener((listView, view1, position, rowId) -> {
@ -167,8 +166,6 @@ public class EpisodesApplyActionFragment extends Fragment {
mAdapter = new ArrayAdapter<>(getActivity(), mAdapter = new ArrayAdapter<>(getActivity(),
R.layout.simple_list_item_multiple_choice_on_start, titles); R.layout.simple_list_item_multiple_choice_on_start, titles);
mListView.setAdapter(mAdapter); mListView.setAdapter(mAdapter);
toolbar = view.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
// Init action UI (via a FAB Speed Dial) // Init action UI (via a FAB Speed Dial)
mSpeedDialView = view.findViewById(R.id.fabSD); mSpeedDialView = view.findViewById(R.id.fabSD);
@ -215,42 +212,15 @@ public class EpisodesApplyActionFragment extends Fragment {
return view; return view;
} }
@Override public void refreshToolbarState() {
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { MenuItem selectAllItem = toolbar.getMenu().findItem(R.id.select_toggle);
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.episodes_apply_action_options, menu);
mSelectToggle = menu.findItem(R.id.select_toggle);
mSelectToggle.setOnMenuItemClickListener(item -> {
if (checkedIds.size() == episodes.size()) {
checkNone();
} else {
checkAll();
}
return true;
});
}
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
// Prepare icon for select toggle button
int[] icon = new int[1];
@StringRes int titleResId;
if (checkedIds.size() == episodes.size()) { if (checkedIds.size() == episodes.size()) {
icon[0] = R.attr.ic_select_none; selectAllItem.setIcon(ThemeUtils.getDrawableFromAttr(getContext(), R.attr.ic_select_none));
titleResId = R.string.deselect_all_label; selectAllItem.setTitle(R.string.deselect_all_label);
} else { } else {
icon[0] = R.attr.ic_select_all; selectAllItem.setIcon(ThemeUtils.getDrawableFromAttr(getContext(), R.attr.ic_select_all));
titleResId = R.string.select_all_label; selectAllItem.setTitle(R.string.select_all_label);
} }
TypedArray a = getActivity().obtainStyledAttributes(icon);
Drawable iconDrawable = a.getDrawable(0);
a.recycle();
mSelectToggle.setIcon(iconDrawable);
mSelectToggle.setTitle(titleResId);
} }
private static final Map<Integer, SortOrder> menuItemIdToSortOrder; private static final Map<Integer, SortOrder> menuItemIdToSortOrder;
@ -266,11 +236,18 @@ public class EpisodesApplyActionFragment extends Fragment {
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
@StringRes int resId = 0; @StringRes int resId = 0;
switch(item.getItemId()) { switch (item.getItemId()) {
case R.id.select_options: case R.id.select_options:
return true; return true;
case R.id.select_toggle:
if (checkedIds.size() == episodes.size()) {
checkNone();
} else {
checkAll();
}
return true;
case R.id.check_all: case R.id.check_all:
checkAll(); checkAll();
resId = R.string.selected_all_label; resId = R.string.selected_all_label;
@ -409,7 +386,7 @@ public class EpisodesApplyActionFragment extends Fragment {
boolean checked = checkedIds.contains(episode.getId()); boolean checked = checkedIds.contains(episode.getId());
mListView.setItemChecked(i, checked); mListView.setItemChecked(i, checked);
} }
getActivity().invalidateOptionsMenu(); refreshToolbarState();
toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label, toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label,
checkedIds.size(), checkedIds.size())); checkedIds.size(), checkedIds.size()));
} }

View File

@ -17,7 +17,7 @@ import android.widget.EditText;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
@ -61,7 +61,8 @@ public class AddFeedFragment extends Fragment {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.addfeed, container, false); View root = inflater.inflate(R.layout.addfeed, container, false);
activity = (MainActivity) getActivity(); activity = (MainActivity) getActivity();
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); Toolbar toolbar = root.findViewById(R.id.toolbar);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
root.findViewById(R.id.btn_search_itunes).setOnClickListener(v root.findViewById(R.id.btn_search_itunes).setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(ItunesPodcastSearcher.class))); -> activity.loadChildFragment(OnlineSearchFragment.newInstance(ItunesPodcastSearcher.class)));
@ -146,11 +147,6 @@ public class AddFeedFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
// So, we certainly *don't* have an options menu,
// but unless we say we do, old options menus sometimes
// persist. mfietz thinks this causes the ActionBar to be invalidated
setHasOptionsMenu(true);
} }
@Override @Override

View File

@ -56,10 +56,11 @@ public class AllEpisodesFragment extends EpisodesListFragment {
} }
@Override @Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onCreateOptionsMenu(menu, inflater); super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.filter_items).setVisible(true); menu.findItem(R.id.filter_items).setVisible(true);
menu.findItem(R.id.mark_all_read_item).setVisible(true); menu.findItem(R.id.mark_all_read_item).setVisible(true);
menu.findItem(R.id.remove_all_new_flags_item).setVisible(false);
} }
@Override @Override

View File

@ -96,12 +96,6 @@ public class CompletedDownloadsFragment extends Fragment {
loadItems(); loadItems();
} }
@Override
public void onResume() {
super.onResume();
setHasOptionsMenu(true);
}
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
@ -111,9 +105,8 @@ public class CompletedDownloadsFragment extends Fragment {
} }
@Override @Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onCreateOptionsMenu(menu, inflater); menu.findItem(R.id.clear_logs_item).setVisible(false);
inflater.inflate(R.menu.downloads_completed, menu);
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0); menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
} }
@ -135,7 +128,7 @@ public class CompletedDownloadsFragment extends Fragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
} }
@ -225,7 +218,7 @@ public class CompletedDownloadsFragment extends Fragment {
.subscribe(result -> { .subscribe(result -> {
items = result; items = result;
adapter.updateItems(result); adapter.updateItems(result);
requireActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
}, error -> Log.e(TAG, Log.getStackTraceString(error))); }, error -> Log.e(TAG, Log.getStackTraceString(error)));
} }

View File

@ -15,7 +15,7 @@ import android.widget.ProgressBar;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
@ -90,7 +90,6 @@ public class DiscoveryFragment extends Fragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE); prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE);
countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, Locale.getDefault().getCountry()); countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, Locale.getDefault().getCountry());
} }
@ -100,11 +99,13 @@ public class DiscoveryFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
gridView = root.findViewById(R.id.gridView); gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
gridView.setAdapter(adapter); gridView.setAdapter(adapter);
Toolbar toolbar = root.findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
//Show information about the podcast when the list item is clicked //Show information about the podcast when the list item is clicked
gridView.setOnItemClickListener((parent, view1, position, id) -> { gridView.setOnItemClickListener((parent, view1, position, id) -> {
PodcastSearchResult podcast = searchResults.get(position); PodcastSearchResult podcast = searchResults.get(position);

View File

@ -65,12 +65,6 @@ public class DownloadLogFragment extends ListFragment {
loadItems(); loadItems();
} }
@Override
public void onResume() {
super.onResume();
setHasOptionsMenu(true);
}
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
@ -108,7 +102,7 @@ public class DownloadLogFragment extends ListFragment {
private void onFragmentLoaded() { private void onFragmentLoaded() {
setListShown(true); setListShown(true);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
getActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
@Override @Override
@ -171,20 +165,11 @@ public class DownloadLogFragment extends ListFragment {
loadItems(); loadItems();
} }
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.downloads_log, menu);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
@Override @Override
public void onPrepareOptionsMenu(@NonNull Menu menu) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu); menu.findItem(R.id.episode_actions).setVisible(false);
MenuItem menuItem = menu.findItem(R.id.clear_history_item); menu.findItem(R.id.clear_logs_item).setVisible(!downloadLog.isEmpty());
if (menuItem != null) { isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
menuItem.setVisible(!downloadLog.isEmpty());
}
} }
@Override @Override
@ -209,7 +194,7 @@ public class DownloadLogFragment extends ListFragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
} }

View File

@ -9,7 +9,6 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
@ -19,11 +18,12 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
/** /**
* Shows the CompletedDownloadsFragment and the RunningDownloadsFragment * Shows the CompletedDownloadsFragment and the RunningDownloadsFragment.
*/ */
public class DownloadsFragment extends Fragment { public class DownloadsFragment extends PagedToolbarFragment {
public static final String TAG = "DownloadsFragment"; public static final String TAG = "DownloadsFragment";
@ -47,11 +47,13 @@ public class DownloadsFragment extends Fragment {
View root = inflater.inflate(R.layout.pager_fragment, container, false); View root = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar); Toolbar toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.downloads_label); toolbar.setTitle(R.string.downloads_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.inflateMenu(R.menu.downloads);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
viewPager = root.findViewById(R.id.viewpager); viewPager = root.findViewById(R.id.viewpager);
viewPager.setAdapter(new DownloadsPagerAdapter(this)); viewPager.setAdapter(new DownloadsPagerAdapter(this));
viewPager.setOffscreenPageLimit(2); viewPager.setOffscreenPageLimit(2);
super.setupPagedToolbar(toolbar, viewPager);
// Give the TabLayout the ViewPager // Give the TabLayout the ViewPager
tabLayout = root.findViewById(R.id.sliding_tabs); tabLayout = root.findViewById(R.id.sliding_tabs);

View File

@ -8,7 +8,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
@ -18,8 +17,10 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
public class EpisodesFragment extends Fragment { public class EpisodesFragment extends PagedToolbarFragment {
public static final String TAG = "EpisodesFragment"; public static final String TAG = "EpisodesFragment";
private static final String PREF_LAST_TAB_POSITION = "tab_position"; private static final String PREF_LAST_TAB_POSITION = "tab_position";
@ -29,18 +30,11 @@ public class EpisodesFragment extends Fragment {
private static final int POS_FAV_EPISODES = 2; private static final int POS_FAV_EPISODES = 2;
private static final int TOTAL_COUNT = 3; private static final int TOTAL_COUNT = 3;
private TabLayout tabLayout; private TabLayout tabLayout;
private ViewPager2 viewPager;
//Mandatory Constructor
public EpisodesFragment() {
}
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
} }
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -48,10 +42,14 @@ public class EpisodesFragment extends Fragment {
View rootView = inflater.inflate(R.layout.pager_fragment, container, false); View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = rootView.findViewById(R.id.toolbar); Toolbar toolbar = rootView.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.episodes_label); toolbar.setTitle(R.string.episodes_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.inflateMenu(R.menu.episodes);
viewPager = rootView.findViewById(R.id.viewpager); MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), 0, "");
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
ViewPager2 viewPager = rootView.findViewById(R.id.viewpager);
viewPager.setAdapter(new EpisodesPagerAdapter(this)); viewPager.setAdapter(new EpisodesPagerAdapter(this));
viewPager.setOffscreenPageLimit(2); viewPager.setOffscreenPageLimit(2);
super.setupPagedToolbar(toolbar, viewPager);
// Give the TabLayout the ViewPager // Give the TabLayout the ViewPager
tabLayout = rootView.findViewById(R.id.sliding_tabs); tabLayout = rootView.findViewById(R.id.sliding_tabs);

View File

@ -13,7 +13,6 @@ import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -76,7 +75,6 @@ public abstract class EpisodesListFragment extends Fragment {
List<FeedItem> episodes = new ArrayList<>(); List<FeedItem> episodes = new ArrayList<>();
private volatile boolean isUpdatingFeeds; private volatile boolean isUpdatingFeeds;
private boolean isMenuVisible = true;
protected Disposable disposable; protected Disposable disposable;
protected TextView txtvInformation; protected TextView txtvInformation;
@ -94,7 +92,6 @@ public abstract class EpisodesListFragment extends Fragment {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
setHasOptionsMenu(true);
registerForContextMenu(recyclerView); registerForContextMenu(recyclerView);
} }
@ -118,19 +115,7 @@ public abstract class EpisodesListFragment extends Fragment {
() -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
@Override @Override
public void setMenuVisibility(final boolean visible) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.setMenuVisibility(visible);
isMenuVisible = visible;
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
if (!isAdded()) {
return;
}
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.episodes, menu);
MenuItemUtils.setupSearchItem(menu, (MainActivity) getActivity(), 0, "");
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
} }
@ -289,8 +274,8 @@ public abstract class EpisodesListFragment extends Fragment {
if (restoreScrollPosition) { if (restoreScrollPosition) {
recyclerView.restoreScrollPosition(getPrefName()); recyclerView.restoreScrollPosition(getPrefName());
} }
if (isMenuVisible && isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
requireActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
} }
@ -344,8 +329,8 @@ public abstract class EpisodesListFragment extends Fragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
DownloaderUpdate update = event.update; DownloaderUpdate update = event.update;
if (isMenuVisible && event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
requireActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
if (update.mediaIds.length > 0) { if (update.mediaIds.length > 0) {
for (long mediaId : update.mediaIds) { for (long mediaId : update.mediaIds) {
@ -359,8 +344,8 @@ public abstract class EpisodesListFragment extends Fragment {
private void updateUi() { private void updateUi() {
loadItems(); loadItems();
if (isMenuVisible && isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
requireActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
} }
@ -391,6 +376,7 @@ public abstract class EpisodesListFragment extends Fragment {
hasMoreItems = true; hasMoreItems = true;
episodes = data; episodes = data;
onFragmentLoaded(episodes); onFragmentLoaded(episodes);
((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
}, error -> Log.e(TAG, Log.getStackTraceString(error))); }, error -> Log.e(TAG, Log.getStackTraceString(error)));
} }

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -42,6 +43,14 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment {
loadItems(); loadItems();
} }
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.filter_items).setVisible(false);
menu.findItem(R.id.mark_all_read_item).setVisible(false);
menu.findItem(R.id.remove_all_new_flags_item).setVisible(false);
}
@NonNull @NonNull
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View File

@ -13,7 +13,6 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -21,8 +20,6 @@ import android.text.TextUtils;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -67,7 +64,7 @@ import java.util.Locale;
/** /**
* Displays information about a feed. * Displays information about a feed.
*/ */
public class FeedInfoFragment extends Fragment { public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId"; private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
private static final String TAG = "FeedInfoActivity"; private static final String TAG = "FeedInfoActivity";
@ -89,7 +86,7 @@ public class FeedInfoFragment extends Fragment {
private ImageView imgvBackground; private ImageView imgvBackground;
private View infoContainer; private View infoContainer;
private View header; private View header;
private Menu optionsMenu; private Toolbar toolbar;
private ToolbarIconTintManager iconTintManager; private ToolbarIconTintManager iconTintManager;
public static FeedInfoFragment newInstance(Feed feed) { public static FeedInfoFragment newInstance(Feed feed) {
@ -119,25 +116,25 @@ public class FeedInfoFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.feedinfo, null); View root = inflater.inflate(R.layout.feedinfo, null);
Toolbar toolbar = root.findViewById(R.id.toolbar); toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(""); toolbar.setTitle("");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.inflateMenu(R.menu.feedinfo);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
toolbar.setOnMenuItemClickListener(this);
refreshToolbarState();
AppBarLayout appBar = root.findViewById(R.id.appBar); AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar); CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) { iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
@Override @Override
protected void doTint(Context themedContext) { protected void doTint(Context themedContext) {
if (optionsMenu == null) { toolbar.getMenu().findItem(R.id.visit_website_item)
return;
}
optionsMenu.findItem(R.id.visit_website_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.location_web_site)); .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.location_web_site));
} }
}; };
iconTintManager.updateTint();
appBar.addOnOffsetChangedListener(iconTintManager); appBar.addOnOffsetChangedListener(iconTintManager);
setHasOptionsMenu(true);
imgvCover = root.findViewById(R.id.imgvCover); imgvCover = root.findViewById(R.id.imgvCover);
txtvTitle = root.findViewById(R.id.txtvTitle); txtvTitle = root.findViewById(R.id.txtvTitle);
txtvAuthorHeader = root.findViewById(R.id.txtvAuthor); txtvAuthorHeader = root.findViewById(R.id.txtvAuthor);
@ -234,7 +231,7 @@ public class FeedInfoFragment extends Fragment {
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}"); txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
Iconify.addIcons(txtvUrl); Iconify.addIcons(txtvUrl);
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
private void loadStatistics() { private void loadStatistics() {
@ -286,29 +283,19 @@ public class FeedInfoFragment extends Fragment {
} }
} }
@Override private void refreshToolbarState() {
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { toolbar.getMenu().findItem(R.id.reconnect_local_folder).setVisible(feed != null && feed.isLocalFeed());
super.onCreateOptionsMenu(menu, inflater); toolbar.getMenu().findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
inflater.inflate(R.menu.feedinfo, menu); toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
optionsMenu = menu;
iconTintManager.updateTint();
}
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.reconnect_local_folder).setVisible(feed != null && feed.isLocalFeed());
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
&& IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink())))); && IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
} }
@Override @Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
if (feed == null) { if (feed == null) {
((MainActivity) getActivity()).showSnackbarAbovePlayer( ((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.please_wait_for_data, Toast.LENGTH_LONG); R.string.please_wait_for_data, Toast.LENGTH_LONG);
return super.onOptionsItemSelected(item); return false;
} }
boolean handled = false; boolean handled = false;
try { try {
@ -335,7 +322,7 @@ public class FeedInfoFragment extends Fragment {
return true; return true;
} }
return handled || super.onOptionsItemSelected(item); return handled;
} }
@Override @Override

View File

@ -10,8 +10,6 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -24,7 +22,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -90,7 +87,8 @@ import java.util.Set;
/** /**
* Displays a list of FeedItems. * Displays a list of FeedItems.
*/ */
public class FeedItemlistFragment extends Fragment implements AdapterView.OnItemClickListener { public class FeedItemlistFragment extends Fragment implements AdapterView.OnItemClickListener,
Toolbar.OnMenuItemClickListener {
private static final String TAG = "ItemlistFragment"; private static final String TAG = "ItemlistFragment";
private static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id"; private static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id";
@ -108,7 +106,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private ImageButton butShowInfo; private ImageButton butShowInfo;
private ImageButton butShowSettings; private ImageButton butShowSettings;
private View header; private View header;
private Menu optionsMenu; private Toolbar toolbar;
private ToolbarIconTintManager iconTintManager; private ToolbarIconTintManager iconTintManager;
private long feedID; private long feedID;
@ -136,7 +134,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
Bundle args = getArguments(); Bundle args = getArguments();
Validate.notNull(args); Validate.notNull(args);
@ -148,9 +145,11 @@ 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) {
View root = inflater.inflate(R.layout.feed_item_list_fragment, container, false); View root = inflater.inflate(R.layout.feed_item_list_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar); toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(""); toolbar.inflateMenu(R.menu.feedlist);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.setOnMenuItemClickListener(this);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
refreshToolbarState();
recyclerView = root.findViewById(R.id.recyclerView); recyclerView = root.findViewById(R.id.recyclerView);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
@ -172,19 +171,17 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) { iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
@Override @Override
protected void doTint(Context themedContext) { protected void doTint(Context themedContext) {
if (optionsMenu == null) { toolbar.getMenu().findItem(R.id.sort_items)
return;
}
optionsMenu.findItem(R.id.sort_items)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_sort)); .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_sort));
optionsMenu.findItem(R.id.filter_items) toolbar.getMenu().findItem(R.id.filter_items)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_filter)); .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_filter));
optionsMenu.findItem(R.id.refresh_item) toolbar.getMenu().findItem(R.id.refresh_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.navigation_refresh)); .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.navigation_refresh));
optionsMenu.findItem(R.id.action_search) toolbar.getMenu().findItem(R.id.action_search)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.action_search)); .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.action_search));
} }
}; };
iconTintManager.updateTint();
appBar.addOnOffsetChangedListener(iconTintManager); appBar.addOnOffsetChangedListener(iconTintManager);
nextPageLoader = new MoreContentListFooterUtil(root.findViewById(R.id.more_content_list_footer)); nextPageLoader = new MoreContentListFooterUtil(root.findViewById(R.id.more_content_list_footer));
@ -243,33 +240,18 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} }
}; };
@Override private void refreshToolbarState() {
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { if (feed == null) {
if (!isAdded()) {
return; return;
} }
super.onCreateOptionsMenu(menu, inflater); MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), feedID, feed.getTitle());
optionsMenu = menu;
FeedMenuHandler.onCreateOptionsMenu(inflater, menu);
iconTintManager.updateTint();
if (feed != null) {
MenuItemUtils.setupSearchItem(menu, (MainActivity) getActivity(), feedID, feed.getTitle());
} else {
MenuItemUtils.setupSearchItem(menu, (MainActivity) getActivity(), feedID, "");
}
if (feed == null || feed.getLink() == null) {
menu.findItem(R.id.share_link_item).setVisible(false);
menu.findItem(R.id.visit_website_item).setVisible(false);
}
isUpdatingFeed = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); toolbar.getMenu().findItem(R.id.share_link_item).setVisible(feed.getLink() != null);
} toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed.getLink() != null);
@Override isUpdatingFeed = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
public void onPrepareOptionsMenu(@NonNull Menu menu) { R.id.refresh_item, updateRefreshMenuItemChecker);
if (feed != null) { FeedMenuHandler.onPrepareOptionsMenu(toolbar.getMenu(), feed);
FeedMenuHandler.onPrepareOptionsMenu(menu, feed);
}
} }
@Override @Override
@ -280,71 +262,67 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} }
@Override @Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.action_search) { if (item.getItemId() == R.id.action_search) {
item.getActionView().post(() -> iconTintManager.updateTint()); item.getActionView().post(() -> iconTintManager.updateTint());
} }
if (super.onOptionsItemSelected(item)) { if (feed == null) {
((MainActivity) getActivity()).showSnackbarAbovePlayer(
R.string.please_wait_for_data, Toast.LENGTH_LONG);
return true; return true;
} else { }
if (feed == null) { boolean feedMenuHandled;
((MainActivity) getActivity()).showSnackbarAbovePlayer( try {
R.string.please_wait_for_data, Toast.LENGTH_LONG); feedMenuHandled = FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed);
return true; } catch (DownloadRequestException e) {
} e.printStackTrace();
try { DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) { return true;
switch (item.getItemId()) { }
case R.id.episode_actions: if (feedMenuHandled) {
int actions = EpisodesApplyActionFragment.ACTION_ALL; return true;
if (feed.isLocalFeed()) { }
// turn off download and delete actions for local feed switch (item.getItemId()) {
actions ^= EpisodesApplyActionFragment.ACTION_DOWNLOAD; case R.id.episode_actions:
actions ^= EpisodesApplyActionFragment.ACTION_DELETE; int actions = EpisodesApplyActionFragment.ACTION_ALL;
} if (feed.isLocalFeed()) {
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment // turn off download and delete actions for local feed
.newInstance(feed.getItems(), actions); actions ^= EpisodesApplyActionFragment.ACTION_DOWNLOAD;
((MainActivity)getActivity()).loadChildFragment(fragment); actions ^= EpisodesApplyActionFragment.ACTION_DELETE;
return true;
case R.id.rename_item:
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(
getActivity(), feed) {
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
}
};
int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
: R.string.feed_delete_confirmation_msg;
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
R.string.remove_feed_label,
getString(messageId, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
dialog.dismiss();
remover.executeAsync();
}
};
conDialog.createNewDialog().show();
return true;
default:
return false;
}
} else {
return true;
} }
} catch (DownloadRequestException e) { EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
e.printStackTrace(); .newInstance(feed.getItems(), actions);
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); ((MainActivity) getActivity()).loadChildFragment(fragment);
return true; return true;
} case R.id.rename_item:
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(
getActivity(), feed) {
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
}
};
int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
: R.string.feed_delete_confirmation_msg;
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
R.string.remove_feed_label,
getString(messageId, feed.getTitle())) {
@Override
public void onConfirmButtonPressed(
DialogInterface dialog) {
dialog.dismiss();
remover.executeAsync();
}
};
conDialog.createNewDialog().show();
return true;
default:
return false;
} }
} }
@ -450,7 +428,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private void updateSyncProgressBarVisibility() { private void updateSyncProgressBarVisibility() {
if (isUpdatingFeed != updateRefreshMenuItemChecker.isRefreshing()) { if (isUpdatingFeed != updateRefreshMenuItemChecker.isRefreshing()) {
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
if (!DownloadRequester.getInstance().isDownloadingFeeds()) { if (!DownloadRequester.getInstance().isDownloadingFeeds()) {
nextPageLoader.getRoot().setVisibility(View.GONE); nextPageLoader.getRoot().setVisibility(View.GONE);
@ -474,7 +452,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
adapter.updateItems(feed.getItems()); adapter.updateItems(feed.getItems());
} }
getActivity().invalidateOptionsMenu(); refreshToolbarState();
updateSyncProgressBarVisibility(); updateSyncProgressBarVisibility();
} }

View File

@ -9,7 +9,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
@ -65,7 +64,7 @@ public class FeedSettingsFragment extends Fragment {
long feedId = getArguments().getLong(EXTRA_FEED_ID); long feedId = getArguments().getLong(EXTRA_FEED_ID);
Toolbar toolbar = root.findViewById(R.id.toolbar); Toolbar toolbar = root.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
getParentFragmentManager().beginTransaction() getParentFragmentManager().beginTransaction()
.replace(R.id.settings_fragment_container, .replace(R.id.settings_fragment_container,

View File

@ -2,15 +2,12 @@ package de.danoeh.antennapod.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -35,7 +32,7 @@ import io.reactivex.schedulers.Schedulers;
/** /**
* Displays information about a list of FeedItems. * Displays information about a list of FeedItems.
*/ */
public class ItemPagerFragment extends Fragment { public class ItemPagerFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
private static final String ARG_FEEDITEMS = "feeditems"; private static final String ARG_FEEDITEMS = "feeditems";
private static final String ARG_FEEDITEM_POS = "feeditem_pos"; private static final String ARG_FEEDITEM_POS = "feeditem_pos";
private static final String KEY_PAGER_ID = "pager_id"; private static final String KEY_PAGER_ID = "pager_id";
@ -60,21 +57,18 @@ public class ItemPagerFragment extends Fragment {
private long[] feedItems; private long[] feedItems;
private FeedItem item; private FeedItem item;
private Disposable disposable; private Disposable disposable;
private Toolbar toolbar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View layout = inflater.inflate(R.layout.feeditem_pager_fragment, container, false); View layout = inflater.inflate(R.layout.feeditem_pager_fragment, container, false);
Toolbar toolbar = layout.findViewById(R.id.toolbar); toolbar = layout.findViewById(R.id.toolbar);
toolbar.setTitle(""); toolbar.setTitle("");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.inflateMenu(R.menu.feeditem_options);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
toolbar.setOnMenuItemClickListener(this);
feedItems = getArguments().getLongArray(ARG_FEEDITEMS); feedItems = getArguments().getLongArray(ARG_FEEDITEMS);
int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS); int feedItemPos = getArguments().getInt(ARG_FEEDITEM_POS);
@ -130,28 +124,25 @@ public class ItemPagerFragment extends Fragment {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {
item = result; item = result;
getActivity().invalidateOptionsMenu(); refreshToolbarState();
}, Throwable::printStackTrace); }, Throwable::printStackTrace);
} }
@Override public void refreshToolbarState() {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (item == null) {
if (!isAdded() || item == null) {
return; return;
} }
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.feeditem_options, menu);
if (item.hasMedia()) { if (item.hasMedia()) {
FeedItemMenuHandler.onPrepareMenu(menu, item); FeedItemMenuHandler.onPrepareMenu(toolbar.getMenu(), item);
} else { } else {
// these are already available via button1 and button2 // these are already available via button1 and button2
FeedItemMenuHandler.onPrepareMenu(menu, item, FeedItemMenuHandler.onPrepareMenu(toolbar.getMenu(), item,
R.id.mark_read_item, R.id.visit_website_item); R.id.mark_read_item, R.id.visit_website_item);
} }
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem menuItem) { public boolean onMenuItemClick(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.open_podcast) { if (menuItem.getItemId() == R.id.open_podcast) {
openPodcast(); openPodcast();
return true; return true;
@ -164,7 +155,7 @@ public class ItemPagerFragment extends Fragment {
for (FeedItem item : event.items) { for (FeedItem item : event.items) {
if (this.item != null && this.item.getId() == item.getId()) { if (this.item != null && this.item.getId() == item.getId()) {
this.item = item; this.item = item;
getActivity().invalidateOptionsMenu(); refreshToolbarState();
return; return;
} }
} }

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuInflater;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
@ -37,8 +38,10 @@ public class NewEpisodesFragment extends EpisodesListFragment {
} }
@Override @Override
public void onPrepareOptionsMenu(Menu menu) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu); super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.filter_items).setVisible(false);
menu.findItem(R.id.mark_all_read_item).setVisible(false);
menu.findItem(R.id.remove_all_new_flags_item).setVisible(true); menu.findItem(R.id.remove_all_new_flags_item).setVisible(true);
} }

View File

@ -2,14 +2,11 @@ package de.danoeh.antennapod.fragment;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.core.view.MenuItemCompat;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -77,7 +74,6 @@ public class OnlineSearchFragment extends Fragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
for (PodcastSearcherRegistry.SearcherInfo info : PodcastSearcherRegistry.getSearchProviders()) { for (PodcastSearcherRegistry.SearcherInfo info : PodcastSearcherRegistry.getSearchProviders()) {
if (info.searcher.getClass().getName().equals(getArguments().getString(ARG_SEARCHER))) { if (info.searcher.getClass().getName().equals(getArguments().getString(ARG_SEARCHER))) {
@ -94,7 +90,7 @@ public class OnlineSearchFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); setupToolbar(root.findViewById(R.id.toolbar));
root.findViewById(R.id.spinner_country).setVisibility(INVISIBLE); root.findViewById(R.id.spinner_country).setVisibility(INVISIBLE);
gridView = root.findViewById(R.id.gridView); gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
@ -126,11 +122,11 @@ public class OnlineSearchFragment extends Fragment {
adapter = null; adapter = null;
} }
@Override private void setupToolbar(Toolbar toolbar) {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { toolbar.inflateMenu(R.menu.online_search);
super.onCreateOptionsMenu(menu, inflater); toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
inflater.inflate(R.menu.online_search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
final SearchView sv = (SearchView) searchItem.getActionView(); final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.search_podcast_hint)); sv.setQueryHint(getString(R.string.search_podcast_hint));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@ -163,7 +159,6 @@ public class OnlineSearchFragment extends Fragment {
if (getArguments().getString(ARG_QUERY, null) != null) { if (getArguments().getString(ARG_QUERY, null) != null) {
sv.setQuery(getArguments().getString(ARG_QUERY, null), true); sv.setQuery(getArguments().getString(ARG_QUERY, null), true);
} }
} }
private void search(String query) { private void search(String query) {

View File

@ -0,0 +1,47 @@
package de.danoeh.antennapod.fragment;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
/**
* Fragment with a ViewPager where the displayed items influence the top toolbar's menu.
* All items share the same general menu items and are just allowed to show/hide them.
*/
public abstract class PagedToolbarFragment extends Fragment {
private Toolbar toolbar;
private ViewPager2 viewPager;
/**
* Invalidate the toolbar menu if the current child fragment is visible.
* @param child The fragment, or null to force-refresh whatever the active fragment is.
*/
void invalidateOptionsMenuIfActive(Fragment child) {
Fragment visibleChild = getChildFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem());
if (visibleChild == child || child == null) {
child.onPrepareOptionsMenu(toolbar.getMenu());
}
}
protected void setupPagedToolbar(Toolbar toolbar, ViewPager2 viewPager) {
this.toolbar = toolbar;
this.viewPager = viewPager;
toolbar.setOnMenuItemClickListener(item -> {
Fragment child = getChildFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem());
if (child != null) {
return child.onOptionsItemSelected(item);
}
return false;
});
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
Fragment child = getChildFragmentManager().findFragmentByTag("f" + position);
if (child != null) {
child.onPrepareOptionsMenu(toolbar.getMenu());
}
}
});
}
}

View File

@ -1,20 +1,15 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.content.res.TypedArray;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
@ -43,7 +38,7 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List; import java.util.List;
public class PlaybackHistoryFragment extends Fragment { public class PlaybackHistoryFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
public static final String TAG = "PlaybackHistoryFragment"; public static final String TAG = "PlaybackHistoryFragment";
private List<FeedItem> playbackHistory; private List<FeedItem> playbackHistory;
@ -52,21 +47,24 @@ public class PlaybackHistoryFragment extends Fragment {
private EpisodeItemListRecyclerView recyclerView; private EpisodeItemListRecyclerView recyclerView;
private EmptyViewHandler emptyView; private EmptyViewHandler emptyView;
private ProgressBar progressBar; private ProgressBar progressBar;
private Toolbar toolbar;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
} }
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.simple_list_fragment, container, false); View root = inflater.inflate(R.layout.simple_list_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar); toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.playback_history_label); toolbar.setTitle(R.string.playback_history_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.setOnMenuItemClickListener(this);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
toolbar.inflateMenu(R.menu.playback_history);
refreshToolbarState();
recyclerView = root.findViewById(R.id.recyclerView); recyclerView = root.findViewById(R.id.recyclerView);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
@ -146,39 +144,18 @@ public class PlaybackHistoryFragment extends Fragment {
} }
} }
@Override public void refreshToolbarState() {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { boolean hasHistory = playbackHistory != null && !playbackHistory.isEmpty();
if (!isAdded()) { toolbar.getMenu().findItem(R.id.clear_history_item).setVisible(hasHistory);
return;
}
super.onCreateOptionsMenu(menu, inflater);
MenuItem clearHistory = menu.add(Menu.NONE, R.id.clear_history_item, Menu.CATEGORY_CONTAINER, R.string.clear_history_label);
clearHistory.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.ic_delete});
clearHistory.setIcon(drawables.getDrawable(0));
drawables.recycle();
} }
@Override @Override
public void onPrepareOptionsMenu(Menu menu) { public boolean onMenuItemClick(MenuItem item) {
super.onPrepareOptionsMenu(menu); if (item.getItemId() == R.id.clear_history_item) {
MenuItem menuItem = menu.findItem(R.id.clear_history_item); DBWriter.clearPlaybackHistory();
if (menuItem != null) {
menuItem.setVisible(playbackHistory != null && !playbackHistory.isEmpty());
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
if (item.getItemId() == R.id.clear_history_item) {
DBWriter.clearPlaybackHistory();
return true;
}
return false;
} else {
return true; return true;
} }
return false;
} }
@Override @Override
@ -194,18 +171,18 @@ public class PlaybackHistoryFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onHistoryUpdated(PlaybackHistoryEvent event) { public void onHistoryUpdated(PlaybackHistoryEvent event) {
loadItems(); loadItems();
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onPlayerStatusChanged(PlayerStatusEvent event) { public void onPlayerStatusChanged(PlayerStatusEvent event) {
loadItems(); loadItems();
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
private void onFragmentLoaded() { private void onFragmentLoaded() {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
private void loadItems() { private void loadItems() {

View File

@ -6,8 +6,6 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -15,7 +13,7 @@ import android.widget.CheckBox;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -67,7 +65,7 @@ import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_REM
/** /**
* Shows all items in the queue. * Shows all items in the queue.
*/ */
public class QueueFragment extends Fragment { public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
public static final String TAG = "QueueFragment"; public static final String TAG = "QueueFragment";
private TextView infoBar; private TextView infoBar;
@ -75,6 +73,7 @@ public class QueueFragment extends Fragment {
private QueueRecyclerAdapter recyclerAdapter; private QueueRecyclerAdapter recyclerAdapter;
private EmptyViewHandler emptyView; private EmptyViewHandler emptyView;
private ProgressBar progLoading; private ProgressBar progLoading;
private Toolbar toolbar;
private List<FeedItem> queue; private List<FeedItem> queue;
@ -91,7 +90,6 @@ public class QueueFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE); prefs = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
} }
@ -182,7 +180,7 @@ public class QueueFragment extends Fragment {
Log.d(TAG, "onEventMainThread() called with DownloadEvent"); Log.d(TAG, "onEventMainThread() called with DownloadEvent");
DownloaderUpdate update = event.update; DownloaderUpdate update = event.update;
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
if (recyclerAdapter != null && update.mediaIds.length > 0) { if (recyclerAdapter != null && update.mediaIds.length > 0) {
for (long mediaId : update.mediaIds) { for (long mediaId : update.mediaIds) {
@ -212,7 +210,7 @@ public class QueueFragment extends Fragment {
public void onPlayerStatusChanged(PlayerStatusEvent event) { public void onPlayerStatusChanged(PlayerStatusEvent event) {
loadItems(false); loadItems(false);
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
} }
@ -221,7 +219,7 @@ public class QueueFragment extends Fragment {
// Sent when playback position is reset // Sent when playback position is reset
loadItems(false); loadItems(false);
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
} }
@ -238,114 +236,94 @@ public class QueueFragment extends Fragment {
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
() -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
@Override private void refreshToolbarState() {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { MenuItemUtils.refreshLockItem(getActivity(), toolbar.getMenu());
if(!isAdded()) { boolean keepSorted = UserPreferences.isQueueKeepSorted();
return; toolbar.getMenu().findItem(R.id.queue_lock).setVisible(!keepSorted);
}
super.onCreateOptionsMenu(menu, inflater);
if (queue != null) {
inflater.inflate(R.menu.queue, menu);
MenuItemUtils.setupSearchItem(menu, (MainActivity) getActivity(), 0, "");
MenuItemUtils.refreshLockItem(getActivity(), menu);
// Show Lock Item only if queue is sorted manually toolbar.getMenu().findItem(R.id.queue_sort_random).setVisible(!keepSorted);
boolean keepSorted = UserPreferences.isQueueKeepSorted(); toolbar.getMenu().findItem(R.id.queue_keep_sorted).setChecked(keepSorted);
MenuItem lockItem = menu.findItem(R.id.queue_lock); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
lockItem.setVisible(!keepSorted); R.id.refresh_item, updateRefreshMenuItemChecker);
// Random sort is not supported in keep sorted mode
MenuItem sortRandomItem = menu.findItem(R.id.queue_sort_random);
sortRandomItem.setVisible(!keepSorted);
// Set keep sorted checkbox
MenuItem keepSortedItem = menu.findItem(R.id.queue_keep_sorted);
keepSortedItem.setChecked(keepSorted);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
if (!super.onOptionsItemSelected(item)) { switch (item.getItemId()) {
switch (item.getItemId()) { case R.id.queue_lock:
case R.id.queue_lock: toggleQueueLock();
toggleQueueLock(); return true;
return true; case R.id.refresh_item:
case R.id.refresh_item: AutoUpdateManager.runImmediate(requireContext());
AutoUpdateManager.runImmediate(requireContext()); return true;
return true; case R.id.clear_queue:
case R.id.clear_queue: // make sure the user really wants to clear the queue
// make sure the user really wants to clear the queue ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(), R.string.clear_queue_label,
R.string.clear_queue_label, R.string.clear_queue_confirmation_msg) {
R.string.clear_queue_confirmation_msg) {
@Override @Override
public void onConfirmButtonPressed( public void onConfirmButtonPressed(
DialogInterface dialog) { DialogInterface dialog) {
dialog.dismiss(); dialog.dismiss();
DBWriter.clearQueue(); DBWriter.clearQueue();
}
};
conDialog.createNewDialog().show();
return true;
case R.id.episode_actions:
((MainActivity) requireActivity()).loadChildFragment(
EpisodesApplyActionFragment.newInstance(queue, ACTION_DELETE | ACTION_REMOVE_FROM_QUEUE | ACTION_DOWNLOAD));
return true;
case R.id.queue_sort_episode_title_asc:
setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
return true;
case R.id.queue_sort_episode_title_desc:
setSortOrder(SortOrder.EPISODE_TITLE_Z_A);
return true;
case R.id.queue_sort_date_asc:
setSortOrder(SortOrder.DATE_OLD_NEW);
return true;
case R.id.queue_sort_date_desc:
setSortOrder(SortOrder.DATE_NEW_OLD);
return true;
case R.id.queue_sort_duration_asc:
setSortOrder(SortOrder.DURATION_SHORT_LONG);
return true;
case R.id.queue_sort_duration_desc:
setSortOrder(SortOrder.DURATION_LONG_SHORT);
return true;
case R.id.queue_sort_feed_title_asc:
setSortOrder(SortOrder.FEED_TITLE_A_Z);
return true;
case R.id.queue_sort_feed_title_desc:
setSortOrder(SortOrder.FEED_TITLE_Z_A);
return true;
case R.id.queue_sort_random:
setSortOrder(SortOrder.RANDOM);
return true;
case R.id.queue_sort_smart_shuffle_asc:
setSortOrder(SortOrder.SMART_SHUFFLE_OLD_NEW);
return true;
case R.id.queue_sort_smart_shuffle_desc:
setSortOrder(SortOrder.SMART_SHUFFLE_NEW_OLD);
return true;
case R.id.queue_keep_sorted:
boolean keepSortedOld = UserPreferences.isQueueKeepSorted();
boolean keepSortedNew = !keepSortedOld;
UserPreferences.setQueueKeepSorted(keepSortedNew);
if (keepSortedNew) {
SortOrder sortOrder = UserPreferences.getQueueKeepSortedOrder();
DBWriter.reorderQueue(sortOrder, true);
} }
if (recyclerAdapter != null) { };
recyclerAdapter.updateDragDropEnabled(); conDialog.createNewDialog().show();
} return true;
getActivity().invalidateOptionsMenu(); case R.id.episode_actions:
return true; ((MainActivity) requireActivity()).loadChildFragment(
default: EpisodesApplyActionFragment.newInstance(queue,
return false; ACTION_DELETE | ACTION_REMOVE_FROM_QUEUE | ACTION_DOWNLOAD));
} return true;
} else { case R.id.queue_sort_episode_title_asc:
return true; setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
return true;
case R.id.queue_sort_episode_title_desc:
setSortOrder(SortOrder.EPISODE_TITLE_Z_A);
return true;
case R.id.queue_sort_date_asc:
setSortOrder(SortOrder.DATE_OLD_NEW);
return true;
case R.id.queue_sort_date_desc:
setSortOrder(SortOrder.DATE_NEW_OLD);
return true;
case R.id.queue_sort_duration_asc:
setSortOrder(SortOrder.DURATION_SHORT_LONG);
return true;
case R.id.queue_sort_duration_desc:
setSortOrder(SortOrder.DURATION_LONG_SHORT);
return true;
case R.id.queue_sort_feed_title_asc:
setSortOrder(SortOrder.FEED_TITLE_A_Z);
return true;
case R.id.queue_sort_feed_title_desc:
setSortOrder(SortOrder.FEED_TITLE_Z_A);
return true;
case R.id.queue_sort_random:
setSortOrder(SortOrder.RANDOM);
return true;
case R.id.queue_sort_smart_shuffle_asc:
setSortOrder(SortOrder.SMART_SHUFFLE_OLD_NEW);
return true;
case R.id.queue_sort_smart_shuffle_desc:
setSortOrder(SortOrder.SMART_SHUFFLE_NEW_OLD);
return true;
case R.id.queue_keep_sorted:
boolean keepSortedOld = UserPreferences.isQueueKeepSorted();
boolean keepSortedNew = !keepSortedOld;
UserPreferences.setQueueKeepSorted(keepSortedNew);
if (keepSortedNew) {
SortOrder sortOrder = UserPreferences.getQueueKeepSortedOrder();
DBWriter.reorderQueue(sortOrder, true);
}
if (recyclerAdapter != null) {
recyclerAdapter.updateDragDropEnabled();
}
refreshToolbarState();
return true;
default:
return false;
} }
} }
@ -378,7 +356,7 @@ public class QueueFragment extends Fragment {
private void setQueueLocked(boolean locked) { private void setQueueLocked(boolean locked) {
UserPreferences.setQueueLocked(locked); UserPreferences.setQueueLocked(locked);
getActivity().invalidateOptionsMenu(); refreshToolbarState();
if (recyclerAdapter != null) { if (recyclerAdapter != null) {
recyclerAdapter.updateDragDropEnabled(); recyclerAdapter.updateDragDropEnabled();
} }
@ -440,7 +418,13 @@ public class QueueFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.queue_fragment, container, false); View root = inflater.inflate(R.layout.queue_fragment, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); toolbar = root.findViewById(R.id.toolbar);
toolbar.setOnMenuItemClickListener(this);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
toolbar.inflateMenu(R.menu.queue);
MenuItemUtils.setupSearchItem(toolbar.getMenu(), (MainActivity) getActivity(), 0, "");
refreshToolbarState();
infoBar = root.findViewById(R.id.info_bar); infoBar = root.findViewById(R.id.info_bar);
recyclerView = root.findViewById(R.id.recyclerView); recyclerView = root.findViewById(R.id.recyclerView);
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
@ -568,7 +552,7 @@ public class QueueFragment extends Fragment {
// we need to refresh the options menu because it sometimes // we need to refresh the options menu because it sometimes
// needs data that may have just been loaded. // needs data that may have just been loaded.
getActivity().invalidateOptionsMenu(); refreshToolbarState();
refreshInfoBar(); refreshInfoBar();
} }

View File

@ -75,12 +75,6 @@ public class RunningDownloadsFragment extends ListFragment {
EventBus.getDefault().register(this); EventBus.getDefault().register(this);
} }
@Override
public void onResume() {
super.onResume();
setHasOptionsMenu(true);
}
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
@ -94,9 +88,9 @@ public class RunningDownloadsFragment extends ListFragment {
} }
@Override @Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onCreateOptionsMenu(menu, inflater); menu.findItem(R.id.clear_logs_item).setVisible(false);
inflater.inflate(R.menu.downloads_running, menu); menu.findItem(R.id.episode_actions).setVisible(false);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
} }
@ -113,7 +107,7 @@ public class RunningDownloadsFragment extends ListFragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
} }
} }

View File

@ -4,16 +4,14 @@ import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -96,7 +94,6 @@ public class SearchFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
} }
@Override @Override
@ -118,7 +115,7 @@ public class SearchFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@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);
((AppCompatActivity) getActivity()).setSupportActionBar(layout.findViewById(R.id.toolbar)); setupToolbar(layout.findViewById(R.id.toolbar));
progressBar = layout.findViewById(R.id.progressBar); progressBar = layout.findViewById(R.id.progressBar);
recyclerView = layout.findViewById(R.id.recyclerView); recyclerView = layout.findViewById(R.id.recyclerView);
@ -154,11 +151,12 @@ public class SearchFragment extends Fragment {
EventBus.getDefault().unregister(this); EventBus.getDefault().unregister(this);
} }
@Override private void setupToolbar(Toolbar toolbar) {
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { toolbar.setTitle(R.string.search_label);
super.onCreateOptionsMenu(menu, inflater); toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
inflater.inflate(R.menu.search, menu); toolbar.inflateMenu(R.menu.search);
MenuItem item = menu.findItem(R.id.action_search);
MenuItem item = toolbar.getMenu().findItem(R.id.action_search);
item.expandActionView(); item.expandActionView();
final SearchView sv = (SearchView) item.getActionView(); final SearchView sv = (SearchView) item.getActionView();
sv.setQueryHint(getString(R.string.search_label)); sv.setQueryHint(getString(R.string.search_label));

View File

@ -9,14 +9,13 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -65,7 +64,7 @@ import org.greenrobot.eventbus.ThreadMode;
/** /**
* Fragment for displaying feed subscriptions * Fragment for displaying feed subscriptions
*/ */
public class SubscriptionFragment extends Fragment { public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
public static final String TAG = "SubscriptionFragment"; public static final String TAG = "SubscriptionFragment";
private static final String PREFS = "SubscriptionFragment"; private static final String PREFS = "SubscriptionFragment";
@ -78,6 +77,7 @@ public class SubscriptionFragment extends Fragment {
private ProgressBar progressBar; private ProgressBar progressBar;
private EmptyViewHandler emptyView; private EmptyViewHandler emptyView;
private TextView feedsFilteredMsg; private TextView feedsFilteredMsg;
private Toolbar toolbar;
private int mPosition = -1; private int mPosition = -1;
private boolean isUpdatingFeeds = false; private boolean isUpdatingFeeds = false;
@ -89,7 +89,6 @@ public class SubscriptionFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setRetainInstance(true); setRetainInstance(true);
setHasOptionsMenu(true);
prefs = requireActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE); prefs = requireActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
} }
@ -98,7 +97,12 @@ public class SubscriptionFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); View root = inflater.inflate(R.layout.fragment_subscriptions, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); toolbar = root.findViewById(R.id.toolbar);
toolbar.setOnMenuItemClickListener(this);
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
toolbar.inflateMenu(R.menu.subscriptions);
refreshToolbarState();
subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid); subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid);
subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns())); subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()));
registerForContextMenu(subscriptionGridLayout); registerForContextMenu(subscriptionGridLayout);
@ -117,25 +121,19 @@ public class SubscriptionFragment extends Fragment {
return root; return root;
} }
@Override private void refreshToolbarState() {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.subscriptions, menu);
int columns = prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()); int columns = prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns());
menu.findItem(R.id.subscription_num_columns_2).setChecked(columns == 2); toolbar.getMenu().findItem(R.id.subscription_num_columns_2).setChecked(columns == 2);
menu.findItem(R.id.subscription_num_columns_3).setChecked(columns == 3); toolbar.getMenu().findItem(R.id.subscription_num_columns_3).setChecked(columns == 3);
menu.findItem(R.id.subscription_num_columns_4).setChecked(columns == 4); toolbar.getMenu().findItem(R.id.subscription_num_columns_4).setChecked(columns == 4);
menu.findItem(R.id.subscription_num_columns_5).setChecked(columns == 5); toolbar.getMenu().findItem(R.id.subscription_num_columns_5).setChecked(columns == 5);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
R.id.refresh_item, updateRefreshMenuItemChecker);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
if (super.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.refresh_item: case R.id.refresh_item:
AutoUpdateManager.runImmediate(requireContext()); AutoUpdateManager.runImmediate(requireContext());
@ -166,7 +164,7 @@ public class SubscriptionFragment extends Fragment {
private void setColumnNumber(int columns) { private void setColumnNumber(int columns) {
subscriptionGridLayout.setNumColumns(columns); subscriptionGridLayout.setNumColumns(columns);
prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply(); prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply();
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
private void setupEmptyView() { private void setupEmptyView() {
@ -361,7 +359,7 @@ public class SubscriptionFragment extends Fragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); refreshToolbarState();
} }
} }

View File

@ -6,7 +6,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
@ -33,7 +32,7 @@ public class GpodnetMainFragment extends Fragment {
View root = inflater.inflate(R.layout.pager_fragment, container, false); View root = inflater.inflate(R.layout.pager_fragment, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar); Toolbar toolbar = root.findViewById(R.id.toolbar);
toolbar.setTitle(R.string.gpodnet_main_label); toolbar.setTitle(R.string.gpodnet_main_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
ViewPager2 viewPager = root.findViewById(R.id.viewpager); ViewPager2 viewPager = root.findViewById(R.id.viewpager);
GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(this); GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(this);

View File

@ -4,15 +4,11 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.core.view.MenuItemCompat;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -46,16 +42,34 @@ public abstract class PodcastListFragment extends Fragment {
private Button butRetry; private Button butRetry;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState); View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false);
setHasOptionsMenu(true); setupToolbar(root.findViewById(R.id.toolbar));
gridView = root.findViewById(R.id.gridView);
progressBar = root.findViewById(R.id.progressBar);
txtvError = root.findViewById(R.id.txtvError);
butRetry = root.findViewById(R.id.butRetry);
gridView.setOnItemClickListener((parent, view, position, id) ->
onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position)));
butRetry.setOnClickListener(v -> loadData());
loadData();
return root;
} }
@Override private void setupToolbar(Toolbar toolbar) {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (getArguments() != null && getArguments().getBoolean(ARGUMENT_HIDE_TOOLBAR, false)) {
super.onCreateOptionsMenu(menu, inflater); toolbar.setVisibility(View.GONE);
inflater.inflate(R.menu.gpodder_podcasts, menu); return;
MenuItem searchItem = menu.findItem(R.id.action_search); }
toolbar.setTitle(R.string.gpodnet_main_label);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
toolbar.inflateMenu(R.menu.gpodder_podcasts);
MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
final SearchView sv = (SearchView) searchItem.getActionView(); final SearchView sv = (SearchView) searchItem.getActionView();
sv.setQueryHint(getString(R.string.gpodnet_search_hint)); sv.setQueryHint(getString(R.string.gpodnet_search_hint));
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@ -76,30 +90,6 @@ public abstract class PodcastListFragment extends Fragment {
}); });
} }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false);
Toolbar toolbar = root.findViewById(R.id.toolbar);
if (getArguments() == null || !getArguments().getBoolean(ARGUMENT_HIDE_TOOLBAR, false)) {
toolbar.setTitle(R.string.gpodnet_main_label);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
} else {
toolbar.setVisibility(View.GONE);
}
gridView = root.findViewById(R.id.gridView);
progressBar = root.findViewById(R.id.progressBar);
txtvError = root.findViewById(R.id.txtvError);
butRetry = root.findViewById(R.id.butRetry);
gridView.setOnItemClickListener((parent, view, position, id) ->
onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position)));
butRetry.setOnClickListener(v -> loadData());
loadData();
return root;
}
private void onPodcastSelected(GpodnetPodcast selection) { private void onPodcastSelected(GpodnetPodcast selection) {
Log.d(TAG, "Selected podcast: " + selection.toString()); Log.d(TAG, "Selected podcast: " + selection.toString());
Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);

View File

@ -34,11 +34,6 @@ public class FeedMenuHandler {
private static final String TAG = "FeedMenuHandler"; private static final String TAG = "FeedMenuHandler";
public static boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) {
inflater.inflate(R.menu.feedlist, menu);
return true;
}
public static boolean onPrepareOptionsMenu(Menu menu, Feed selectedFeed) { public static boolean onPrepareOptionsMenu(Menu menu, Feed selectedFeed) {
if (selectedFeed == null) { if (selectedFeed == null) {
return true; return true;

View File

@ -1,9 +1,10 @@
package de.danoeh.antennapod.menuhandler; package de.danoeh.antennapod.menuhandler;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.appcompat.view.menu.MenuItemImpl;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.MainActivity;
@ -11,24 +12,23 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.ThemeUtils; import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.fragment.SearchFragment; import de.danoeh.antennapod.fragment.SearchFragment;
import java.util.HashMap;
import java.util.Map;
/** /**
* Utilities for menu items * Utilities for menu items.
*/ */
public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuItemUtils { public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuItemUtils {
@SuppressWarnings("ResourceType")
public static void refreshLockItem(Context context, Menu menu) { public static void refreshLockItem(Context context, Menu menu) {
final MenuItem queueLock = menu.findItem(de.danoeh.antennapod.R.id.queue_lock); final MenuItem queueLock = menu.findItem(R.id.queue_lock);
int[] lockIcons = new int[] { de.danoeh.antennapod.R.attr.ic_lock_open, de.danoeh.antennapod.R.attr.ic_lock_closed };
TypedArray ta = context.obtainStyledAttributes(lockIcons);
if (UserPreferences.isQueueLocked()) { if (UserPreferences.isQueueLocked()) {
queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue); queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue);
queueLock.setIcon(ta.getDrawable(0)); queueLock.setIcon(ThemeUtils.getDrawableFromAttr(context, R.attr.ic_lock_open));
} else { } else {
queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue); queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue);
queueLock.setIcon(ta.getDrawable(1)); queueLock.setIcon(ThemeUtils.getDrawableFromAttr(context, R.attr.ic_lock_closed));
} }
ta.recycle();
} }
public static void setupSearchItem(Menu menu, MainActivity activity, long feedId, String feedTitle) { public static void setupSearchItem(Menu menu, MainActivity activity, long feedId, String feedTitle) {
@ -51,21 +51,49 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
} }
}); });
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
private final Map<Integer, Integer> oldShowAsActionState = new HashMap<>();
@Override @Override
public boolean onMenuItemActionExpand(MenuItem item) { public boolean onMenuItemActionExpand(MenuItem clickedItem) {
oldShowAsActionState.clear();
for (int i = 0; i < menu.size(); i++) { for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).getItemId() != searchItem.getItemId()) { MenuItem item = menu.getItem(i);
menu.getItem(i).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); if (item.getItemId() != searchItem.getItemId()) {
oldShowAsActionState.put(item.getItemId(), getShowAsActionFlag(item));
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
} }
} }
return true; return true;
} }
@Override @Override
public boolean onMenuItemActionCollapse(MenuItem item) { public boolean onMenuItemActionCollapse(MenuItem collapsedItem) {
activity.invalidateOptionsMenu(); 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; 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

@ -6,6 +6,14 @@
android:menuCategory="container" android:menuCategory="container"
android:title="@string/multi_select" android:title="@string/multi_select"
android:icon="?attr/checkbox_multiple" android:icon="?attr/checkbox_multiple"
android:visible="false"
app:showAsAction="ifRoom" />
<item
android:id="@+id/clear_logs_item"
android:menuCategory="container"
android:title="@string/clear_history_label"
android:icon="?attr/ic_delete"
android:visible="false"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item <item
android:id="@+id/refresh_item" android:id="@+id/refresh_item"

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/clear_history_item"
android:menuCategory="container"
android:title="@string/clear_history_label"
android:icon="?attr/ic_delete"
app:showAsAction="ifRoom" />
<item
android:id="@+id/refresh_item"
android:title="@string/refresh_label"
android:menuCategory="container"
app:showAsAction="ifRoom"
android:icon="?attr/navigation_refresh"/>
</menu>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/refresh_item"
android:title="@string/refresh_label"
android:menuCategory="container"
app:showAsAction="ifRoom"
android:icon="?attr/navigation_refresh"/>
</menu>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/clear_history_item"
android:icon="?attr/ic_delete"
android:title="@string/clear_history_label"
app:showAsAction="ifRoom"/>
</menu>