From 0b431a331128bfcf7af3a6512623df74e38b5776 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 22 Apr 2022 20:53:29 +0200 Subject: [PATCH] Update filter dialog to Fragment --- .../dialog/AllEpisodesFilterDialog.java | 31 +++++++ .../dialog/FeedItemFilterDialog.java | 26 ++++++ .../antennapod/dialog/FilterDialog.java | 83 ------------------- .../antennapod/dialog/ItemFilterDialog.java | 75 +++++++++++++++++ .../fragment/AllEpisodesFragment.java | 41 ++++----- .../fragment/FeedItemlistFragment.java | 27 ++---- app/src/main/res/layout/filter_dialog_row.xml | 21 +++-- .../antennapod/model/feed/FeedItemFilter.java | 4 +- .../ui/common/RecursiveRadioGroup.java | 12 +++ 9 files changed, 182 insertions(+), 138 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java create mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java create mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java new file mode 100644 index 000000000..f47a8f8eb --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AllEpisodesFilterDialog.java @@ -0,0 +1,31 @@ +package de.danoeh.antennapod.dialog; + +import android.os.Bundle; +import de.danoeh.antennapod.model.feed.FeedItemFilter; +import org.greenrobot.eventbus.EventBus; + +import java.util.Set; + +public class AllEpisodesFilterDialog extends ItemFilterDialog { + + public static AllEpisodesFilterDialog newInstance(FeedItemFilter filter) { + AllEpisodesFilterDialog dialog = new AllEpisodesFilterDialog(); + Bundle arguments = new Bundle(); + arguments.putSerializable(ARGUMENT_FILTER, filter); + dialog.setArguments(arguments); + return dialog; + } + + @Override + void onFilterChanged(Set newFilterValues) { + EventBus.getDefault().post(new AllEpisodesFilterChangedEvent(newFilterValues)); + } + + public static class AllEpisodesFilterChangedEvent { + public final Set filterValues; + + public AllEpisodesFilterChangedEvent(Set filterValues) { + this.filterValues = filterValues; + } + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java new file mode 100644 index 000000000..e91e88fbf --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemFilterDialog.java @@ -0,0 +1,26 @@ +package de.danoeh.antennapod.dialog; + +import android.os.Bundle; +import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.model.feed.Feed; + +import java.util.Set; + +public class FeedItemFilterDialog extends ItemFilterDialog { + private static final String ARGUMENT_FEED_ID = "feedId"; + + public static FeedItemFilterDialog newInstance(Feed feed) { + FeedItemFilterDialog dialog = new FeedItemFilterDialog(); + Bundle arguments = new Bundle(); + arguments.putSerializable(ARGUMENT_FILTER, feed.getItemFilter()); + arguments.putLong(ARGUMENT_FEED_ID, feed.getId()); + dialog.setArguments(arguments); + return dialog; + } + + @Override + void onFilterChanged(Set newFilterValues) { + long feedId = getArguments().getLong(ARGUMENT_FEED_ID); + DBWriter.setFeedItemsFilter(feedId, newFilterValues); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java deleted file mode 100644 index 593b055f6..000000000 --- a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.danoeh.antennapod.dialog; - -import android.content.Context; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.RadioButton; - -import androidx.appcompat.app.AlertDialog; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.model.feed.FeedItemFilter; -import de.danoeh.antennapod.core.feed.FeedItemFilterGroup; -import de.danoeh.antennapod.ui.common.RecursiveRadioGroup; - -public abstract class FilterDialog { - - protected FeedItemFilter filter; - protected Context context; - - public FilterDialog(Context context, FeedItemFilter feedItemFilter) { - this.context = context; - this.filter = feedItemFilter; - } - - public void openDialog() { - - final Set filterValues = new HashSet<>(Arrays.asList(filter.getValues())); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.filter); - - LayoutInflater inflater = LayoutInflater.from(this.context); - View layout = inflater.inflate(R.layout.filter_dialog, null, false); - LinearLayout rows = layout.findViewById(R.id.filter_rows); - builder.setView(layout); - - for (FeedItemFilterGroup item : FeedItemFilterGroup.values()) { - RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null, false); - RadioButton filter1 = row.findViewById(R.id.filter_dialog_radioButton1); - RadioButton filter2 = row.findViewById(R.id.filter_dialog_radioButton2); - filter1.setText(item.values[0].displayName); - filter1.setTag(item.values[0].filterId); - filter2.setText(item.values[1].displayName); - filter2.setTag(item.values[1].filterId); - rows.addView(row); - } - - for (String filterId : filterValues) { - if (!TextUtils.isEmpty(filterId)) { - RadioButton button = layout.findViewWithTag(filterId); - if (button != null) { - button.setChecked(true); - } - } - } - - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - filterValues.clear(); - for (int i = 0; i < rows.getChildCount(); i++) { - if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) { - continue; - } - RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i); - if (group.getCheckedButton() != null) { - String tag = (String) group.getCheckedButton().getTag(); - if (tag != null) { // Clear buttons use no tag - filterValues.add((String) group.getCheckedButton().getTag()); - } - } - } - updateFilter(filterValues); - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); - } - - protected abstract void updateFilter(Set filterValues); -} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java new file mode 100644 index 000000000..ae938a6ec --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/ItemFilterDialog.java @@ -0,0 +1,75 @@ +package de.danoeh.antennapod.dialog; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.FeedItemFilterGroup; +import de.danoeh.antennapod.model.feed.FeedItemFilter; +import de.danoeh.antennapod.ui.common.RecursiveRadioGroup; + +import java.util.HashSet; +import java.util.Set; + +public abstract class ItemFilterDialog extends BottomSheetDialogFragment { + protected static final String ARGUMENT_FILTER = "filter"; + + private LinearLayout rows; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View layout = inflater.inflate(R.layout.filter_dialog, null, false); + rows = layout.findViewById(R.id.filter_rows); + FeedItemFilter filter = (FeedItemFilter) getArguments().getSerializable(ARGUMENT_FILTER); + + for (FeedItemFilterGroup item : FeedItemFilterGroup.values()) { + RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null, false); + row.setOnCheckedChangeListener((group, checkedId) -> onFilterChanged(getNewFilterValues())); + RadioButton filter1 = row.findViewById(R.id.filter_dialog_radioButton1); + RadioButton filter2 = row.findViewById(R.id.filter_dialog_radioButton2); + filter1.setText(item.values[0].displayName); + filter1.setTag(item.values[0].filterId); + filter2.setText(item.values[1].displayName); + filter2.setTag(item.values[1].filterId); + rows.addView(row); + } + + for (String filterId : filter.getValues()) { + if (!TextUtils.isEmpty(filterId)) { + RadioButton button = layout.findViewWithTag(filterId); + if (button != null) { + button.setChecked(true); + } + } + } + return layout; + } + + protected Set getNewFilterValues() { + final Set newFilterValues = new HashSet<>(); + for (int i = 0; i < rows.getChildCount(); i++) { + if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) { + continue; + } + RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i); + if (group.getCheckedButton() != null) { + String tag = (String) group.getCheckedButton().getTag(); + if (tag != null) { // Clear buttons use no tag + newFilterValues.add((String) group.getCheckedButton().getTag()); + } + } + } + return newFilterValues; + } + + abstract void onFilterChanged(Set newFilterValues); +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index f65c6fdc6..706e47135 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -10,14 +10,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.joanzapata.iconify.Iconify; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.dialog.AllEpisodesFilterDialog; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedItemFilter; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.dialog.FilterDialog; import org.apache.commons.lang3.StringUtils; +import org.greenrobot.eventbus.Subscribe; import java.util.List; -import java.util.Set; /** * Like 'EpisodesFragment' except that it only shows new episodes and @@ -43,15 +43,22 @@ public class AllEpisodesFragment extends EpisodesListFragment { @Override public boolean onOptionsItemSelected(MenuItem item) { - if (!super.onOptionsItemSelected(item)) { - if (item.getItemId() == R.id.filter_items) { - showFilterDialog(); - return true; - } - return false; - } else { + if (super.onOptionsItemSelected(item)) { return true; } + if (item.getItemId() == R.id.filter_items) { + AllEpisodesFilterDialog.newInstance(feedItemFilter).show(getChildFragmentManager(), null); + return true; + } + return false; + } + + @Subscribe + public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) { + feedItemFilter = new FeedItemFilter(event.filterValues.toArray(new String[0])); + SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + prefs.edit().putString(PREF_FILTER, StringUtils.join(event.filterValues, ",")).apply(); + loadItems(); } @Override @@ -75,20 +82,6 @@ public class AllEpisodesFragment extends EpisodesListFragment { } } - private void showFilterDialog() { - FilterDialog filterDialog = new FilterDialog(getContext(), feedItemFilter) { - @Override - protected void updateFilter(Set filterValues) { - feedItemFilter = new FeedItemFilter(filterValues.toArray(new String[0])); - SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - prefs.edit().putString(PREF_FILTER, StringUtils.join(filterValues, ",")).apply(); - loadItems(); - } - }; - - filterDialog.openDialog(); - } - @Override protected boolean shouldUpdatedItemRemainInList(FeedItem item) { SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index 4b367fe42..bb20cb4bc 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -39,14 +39,13 @@ import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.FeedItemPermutors; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; import de.danoeh.antennapod.databinding.FeedItemListFragmentBinding; import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding; import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog; -import de.danoeh.antennapod.dialog.FilterDialog; +import de.danoeh.antennapod.dialog.FeedItemFilterDialog; import de.danoeh.antennapod.dialog.RemoveFeedDialog; import de.danoeh.antennapod.dialog.RenameItemDialog; import de.danoeh.antennapod.event.FavoritesEvent; @@ -77,7 +76,6 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.List; -import java.util.Set; /** * Displays a list of FeedItems. @@ -469,17 +467,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem viewBinding.header.txtvInformation.setText("{md-info-outline} " + this.getString(R.string.filtered_label)); Iconify.addIcons(viewBinding.header.txtvInformation); - viewBinding.header.txtvInformation.setOnClickListener((l) -> { - FilterDialog filterDialog = new FilterDialog(requireContext(), feed.getItemFilter()) { - @Override - protected void updateFilter(Set filterValues) { - feed.setItemFilter(filterValues.toArray(new String[0])); - DBWriter.setFeedItemsFilter(feed.getId(), filterValues); - } - }; - - filterDialog.openDialog(); - }); + viewBinding.header.txtvInformation.setOnClickListener(l -> + FeedItemFilterDialog.newInstance(feed).show(getChildFragmentManager(), null)); viewBinding.header.txtvInformation.setVisibility(View.VISIBLE); } else { viewBinding.header.txtvInformation.setVisibility(View.GONE); @@ -504,14 +493,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem ((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE); } }); - viewBinding.header.butFilter.setOnClickListener( - v -> new FilterDialog(getContext(), feed.getItemFilter()) { - @Override - protected void updateFilter(Set filterValues) { - feed.setItemFilter(filterValues.toArray(new String[0])); - DBWriter.setFeedItemsFilter(feed.getId(), filterValues); - } - }.openDialog()); + viewBinding.header.butFilter.setOnClickListener(v -> + FeedItemFilterDialog.newInstance(feed).show(getChildFragmentManager(), null)); viewBinding.header.txtvFailure.setOnClickListener(v -> showErrorDetails()); headerCreated = true; } diff --git a/app/src/main/res/layout/filter_dialog_row.xml b/app/src/main/res/layout/filter_dialog_row.xml index 914525387..7ecfc8223 100644 --- a/app/src/main/res/layout/filter_dialog_row.xml +++ b/app/src/main/res/layout/filter_dialog_row.xml @@ -12,6 +12,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:clipChildren="true" + android:layout_gravity="center_vertical" app:cardCornerRadius="32dp" app:cardElevation="0dp"> @@ -28,34 +29,38 @@ android:layout_marginRight="2dp" android:layout_weight="1" android:background="?attr/filter_dialog_button_background" - style="@style/NoButtonRadio" + android:minHeight="40dp" android:foreground="?android:attr/selectableItemBackground" android:checked="false" android:gravity="center" - android:textColor="@color/filter_dialog_button_text" /> + android:textColor="@color/filter_dialog_button_text" + style="@style/NoButtonRadio" /> + android:textColor="@color/filter_dialog_button_text" + style="@style/NoButtonRadio" /> + + + android:checked="true" + style="@style/NoButtonRadio" /> diff --git a/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java b/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java index 4f0736c58..c9989e60a 100644 --- a/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java +++ b/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java @@ -1,9 +1,11 @@ package de.danoeh.antennapod.model.feed; import android.text.TextUtils; + +import java.io.Serializable; import java.util.Arrays; -public class FeedItemFilter { +public class FeedItemFilter implements Serializable { private final String[] properties; diff --git a/ui/common/src/main/java/de/danoeh/antennapod/ui/common/RecursiveRadioGroup.java b/ui/common/src/main/java/de/danoeh/antennapod/ui/common/RecursiveRadioGroup.java index 94ef73ffc..578208be4 100644 --- a/ui/common/src/main/java/de/danoeh/antennapod/ui/common/RecursiveRadioGroup.java +++ b/ui/common/src/main/java/de/danoeh/antennapod/ui/common/RecursiveRadioGroup.java @@ -6,6 +6,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RadioButton; +import android.widget.RadioGroup; +import androidx.annotation.Nullable; + import java.util.ArrayList; /** @@ -15,6 +18,8 @@ import java.util.ArrayList; public class RecursiveRadioGroup extends LinearLayout { private final ArrayList radioButtons = new ArrayList<>(); private RadioButton checkedButton = null; + @Nullable + private RadioGroup.OnCheckedChangeListener checkedChangeListener; public RecursiveRadioGroup(Context context) { super(context); @@ -34,6 +39,10 @@ public class RecursiveRadioGroup extends LinearLayout { parseChild(child); } + public void setOnCheckedChangeListener(@Nullable RadioGroup.OnCheckedChangeListener listener) { + checkedChangeListener = listener; + } + public void parseChild(final View child) { if (child instanceof RadioButton) { RadioButton button = (RadioButton) child; @@ -43,6 +52,9 @@ public class RecursiveRadioGroup extends LinearLayout { return; } checkedButton = (RadioButton) buttonView; + if (checkedChangeListener != null) { + checkedChangeListener.onCheckedChanged(null, checkedButton.getId()); + } for (RadioButton view : radioButtons) { if (view != buttonView) {