Use segmented buttons for filter
This commit is contained in:
parent
2740816bb8
commit
37b49b1e38
|
@ -5,15 +5,16 @@ import android.text.TextUtils;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.FeedItemFilterGroup;
|
||||
import de.danoeh.antennapod.databinding.FilterDialogRowBinding;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.ui.common.RecursiveRadioGroup;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -32,22 +33,21 @@ public abstract class ItemFilterDialog extends BottomSheetDialogFragment {
|
|||
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);
|
||||
FilterDialogRowBinding binding = FilterDialogRowBinding.inflate(inflater);
|
||||
binding.getRoot().addOnButtonCheckedListener(
|
||||
(group, checkedId, isChecked) -> onFilterChanged(getNewFilterValues()));
|
||||
binding.filterButton1.setText(item.values[0].displayName);
|
||||
binding.filterButton1.setTag(item.values[0].filterId);
|
||||
binding.filterButton2.setText(item.values[1].displayName);
|
||||
binding.filterButton2.setTag(item.values[1].filterId);
|
||||
rows.addView(binding.getRoot());
|
||||
}
|
||||
|
||||
for (String filterId : filter.getValues()) {
|
||||
if (!TextUtils.isEmpty(filterId)) {
|
||||
RadioButton button = layout.findViewWithTag(filterId);
|
||||
Button button = layout.findViewWithTag(filterId);
|
||||
if (button != null) {
|
||||
button.setChecked(true);
|
||||
((MaterialButtonToggleGroup) button.getParent()).check(button.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,16 +57,18 @@ public abstract class ItemFilterDialog extends BottomSheetDialogFragment {
|
|||
protected Set<String> getNewFilterValues() {
|
||||
final Set<String> newFilterValues = new HashSet<>();
|
||||
for (int i = 0; i < rows.getChildCount(); i++) {
|
||||
if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
|
||||
if (!(rows.getChildAt(i) instanceof MaterialButtonToggleGroup)) {
|
||||
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());
|
||||
MaterialButtonToggleGroup group = (MaterialButtonToggleGroup) rows.getChildAt(i);
|
||||
if (group.getCheckedButtonId() == View.NO_ID) {
|
||||
continue;
|
||||
}
|
||||
String tag = (String) group.findViewById(group.getCheckedButtonId()).getTag();
|
||||
if (tag == null) { // Clear buttons use no tag
|
||||
continue;
|
||||
}
|
||||
newFilterValues.add(tag);
|
||||
}
|
||||
return newFilterValues;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@ import android.content.Context;
|
|||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import de.danoeh.antennapod.databinding.FilterDialogRowBinding;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -20,7 +22,6 @@ import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
|
|||
import de.danoeh.antennapod.model.feed.SubscriptionsFilter;
|
||||
import de.danoeh.antennapod.core.feed.SubscriptionsFilterGroup;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.common.RecursiveRadioGroup;
|
||||
|
||||
public class SubscriptionsFilterDialog {
|
||||
public static void showDialog(Context context) {
|
||||
|
@ -35,39 +36,42 @@ public class SubscriptionsFilterDialog {
|
|||
builder.setView(layout);
|
||||
|
||||
for (SubscriptionsFilterGroup item : SubscriptionsFilterGroup.values()) {
|
||||
RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null);
|
||||
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);
|
||||
FilterDialogRowBinding binding = FilterDialogRowBinding.inflate(inflater);
|
||||
binding.filterButton1.setText(item.values[0].displayName);
|
||||
binding.filterButton1.setTag(item.values[0].filterId);
|
||||
if (item.values.length == 2) {
|
||||
filter2.setText(item.values[1].displayName);
|
||||
filter2.setTag(item.values[1].filterId);
|
||||
binding.filterButton2.setText(item.values[1].displayName);
|
||||
binding.filterButton2.setTag(item.values[1].filterId);
|
||||
} else {
|
||||
filter2.setVisibility(View.GONE);
|
||||
binding.filterButton2.setVisibility(View.GONE);
|
||||
}
|
||||
rows.addView(row);
|
||||
rows.addView(binding.getRoot());
|
||||
}
|
||||
|
||||
for (String filterId : filterValues) {
|
||||
if (!TextUtils.isEmpty(filterId)) {
|
||||
((RadioButton) layout.findViewWithTag(filterId)).setChecked(true);
|
||||
Button button = layout.findViewWithTag(filterId);
|
||||
if (button != null) {
|
||||
((MaterialButtonToggleGroup) button.getParent()).check(button.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
|
||||
filterValues.clear();
|
||||
for (int i = 0; i < rows.getChildCount(); i++) {
|
||||
if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
|
||||
if (!(rows.getChildAt(i) instanceof MaterialButtonToggleGroup)) {
|
||||
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());
|
||||
MaterialButtonToggleGroup group = (MaterialButtonToggleGroup) rows.getChildAt(i);
|
||||
if (group.getCheckedButtonId() == View.NO_ID) {
|
||||
continue;
|
||||
}
|
||||
String tag = (String) group.findViewById(group.getCheckedButtonId()).getTag();
|
||||
if (tag == null) { // Clear buttons use no tag
|
||||
continue;
|
||||
}
|
||||
filterValues.add(tag);
|
||||
}
|
||||
updateFilter(filterValues);
|
||||
});
|
||||
|
|
|
@ -1,66 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<de.danoeh.antennapod.ui.common.RecursiveRadioGroup
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="8dp"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="2"
|
||||
app:singleSelection="true">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<Button
|
||||
android:id="@+id/filterButton1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:clipChildren="true"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:cardCornerRadius="32dp"
|
||||
app:cardElevation="0dp">
|
||||
style="?attr/materialButtonOutlinedStyle" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/filter_dialog_radioButton1"
|
||||
<Button
|
||||
android:id="@+id/filterButton2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/filter_dialog_button_background"
|
||||
android:minHeight="40dp"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:checked="false"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/filter_dialog_button_text"
|
||||
style="@style/NoButtonRadio" />
|
||||
style="?attr/materialButtonOutlinedStyle" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/filter_dialog_radioButton2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:minHeight="40dp"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/filter_dialog_button_background"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:checked="false"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/filter_dialog_button_text"
|
||||
style="@style/NoButtonRadio" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/filter_dialog_clear"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/ic_filter_close"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="true"
|
||||
style="@style/NoButtonRadio" />
|
||||
|
||||
</de.danoeh.antennapod.ui.common.RecursiveRadioGroup>
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorOnSecondary" android:state_checked="true" />
|
||||
<item android:color="?android:textColorPrimary" />
|
||||
</selector>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/dialog_filter_inactive_dark" android:state_checked="true" />
|
||||
<item android:color="@color/dialog_filter_clear_inactive_dark" />
|
||||
</selector>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/dialog_filter_inactive_light" android:state_checked="true" />
|
||||
<item android:color="@color/dialog_filter_clear_inactive_light" />
|
||||
</selector>
|
|
@ -1,55 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:bottom="5dp"
|
||||
android:left="5dp"
|
||||
android:right="5dp"
|
||||
android:top="5dp">
|
||||
|
||||
<shape android:shape="oval">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="?attr/filter_dialog_clear" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- x -->
|
||||
<item
|
||||
android:bottom="12dp"
|
||||
android:left="12dp"
|
||||
android:right="12dp"
|
||||
android:top="12dp">
|
||||
<rotate
|
||||
android:fromDegrees="135"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:toDegrees="135">
|
||||
<shape android:shape="line">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="?attr/filter_dialog_clear" />
|
||||
</shape>
|
||||
</rotate>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:bottom="12dp"
|
||||
android:left="12dp"
|
||||
android:right="12dp"
|
||||
android:top="12dp">
|
||||
<rotate
|
||||
android:fromDegrees="45"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:toDegrees="45">
|
||||
<shape android:shape="line">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="?attr/filter_dialog_clear" />
|
||||
</shape>
|
||||
|
||||
</rotate>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/accent_dark" android:state_checked="true"/>
|
||||
<item android:drawable="@color/dialog_filter_inactive_dark" />
|
||||
</selector>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/accent_light" android:state_checked="true"/>
|
||||
<item android:drawable="@color/dialog_filter_inactive_light" />
|
||||
</selector>
|
|
@ -1,55 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Fall-back for old Android devices that do not support attrs as colors -->
|
||||
<item
|
||||
android:bottom="5dp"
|
||||
android:left="5dp"
|
||||
android:right="5dp"
|
||||
android:top="5dp">
|
||||
|
||||
<shape android:shape="oval">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="#555" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<!-- x -->
|
||||
<item
|
||||
android:bottom="12dp"
|
||||
android:left="12dp"
|
||||
android:right="12dp"
|
||||
android:top="12dp">
|
||||
<rotate
|
||||
android:fromDegrees="135"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:toDegrees="135">
|
||||
<shape android:shape="line">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="#555" />
|
||||
</shape>
|
||||
</rotate>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:bottom="12dp"
|
||||
android:left="12dp"
|
||||
android:right="12dp"
|
||||
android:top="12dp">
|
||||
<rotate
|
||||
android:fromDegrees="45"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:toDegrees="45">
|
||||
<shape android:shape="line">
|
||||
<stroke
|
||||
android:width="4dp"
|
||||
android:color="#555" />
|
||||
</shape>
|
||||
|
||||
</rotate>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
|
@ -10,8 +10,6 @@
|
|||
<attr name="scrollbar_thumb" format="reference"/>
|
||||
<attr name="background_color" format="color"/>
|
||||
<attr name="background_elevated" format="color"/>
|
||||
<attr name="filter_dialog_clear" format="color"/>
|
||||
<attr name="filter_dialog_button_background" format="reference"/>
|
||||
<attr name="seek_background" format="color" />
|
||||
<attr name="icon_red" format="color" />
|
||||
<attr name="icon_yellow" format="color" />
|
||||
|
|
|
@ -35,10 +35,4 @@
|
|||
|
||||
<color name="master_switch_background_light">#DDDDDD</color>
|
||||
<color name="master_switch_background_dark">#191919</color>
|
||||
|
||||
<!-- filter dialog -->
|
||||
<color name="dialog_filter_clear_inactive_light">#666666</color>
|
||||
<color name="dialog_filter_clear_inactive_dark">#bbbbbb</color>
|
||||
<color name="dialog_filter_inactive_light">#eeeeee</color>
|
||||
<color name="dialog_filter_inactive_dark">#555555</color>
|
||||
</resources>
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
<item name="navigation_up">@drawable/navigation_up</item>
|
||||
<item name="dragview_background">@drawable/ic_drag_lighttheme</item>
|
||||
<item name="scrollbar_thumb">@drawable/scrollbar_thumb_light</item>
|
||||
<item name="filter_dialog_clear">@color/filter_dialog_clear_light</item>
|
||||
<item name="filter_dialog_button_background">@drawable/filter_dialog_background_light</item>
|
||||
<item name="icon_red">#CF1800</item>
|
||||
<item name="icon_yellow">#F59F00</item>
|
||||
<item name="icon_green">#008537</item>
|
||||
|
@ -74,8 +72,6 @@
|
|||
<item name="navigation_up">@drawable/navigation_up_dark</item>
|
||||
<item name="dragview_background">@drawable/ic_drag_darktheme</item>
|
||||
<item name="scrollbar_thumb">@drawable/scrollbar_thumb_dark</item>
|
||||
<item name="filter_dialog_clear">@color/filter_dialog_clear_dark</item>
|
||||
<item name="filter_dialog_button_background">@drawable/filter_dialog_background_dark</item>
|
||||
<item name="icon_red">#CF1800</item>
|
||||
<item name="icon_yellow">#F59F00</item>
|
||||
<item name="icon_green">#008537</item>
|
||||
|
@ -250,9 +246,4 @@
|
|||
<item name="android:clickable">true</item>
|
||||
</style>
|
||||
|
||||
<style name="NoButtonRadio" parent="Widget.Material3.CompoundButton.RadioButton">
|
||||
<item name="buttonCompat">@null</item> <!-- For Android 4.4 -->
|
||||
<item name="android:button">@null</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
package de.danoeh.antennapod.ui.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
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;
|
||||
|
||||
/**
|
||||
* An alternative to {@link android.widget.RadioGroup} that allows to nest children.
|
||||
* Basend on https://stackoverflow.com/a/14309274.
|
||||
*/
|
||||
public class RecursiveRadioGroup extends LinearLayout {
|
||||
private final ArrayList<RadioButton> radioButtons = new ArrayList<>();
|
||||
private RadioButton checkedButton = null;
|
||||
@Nullable
|
||||
private RadioGroup.OnCheckedChangeListener checkedChangeListener;
|
||||
|
||||
public RecursiveRadioGroup(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public RecursiveRadioGroup(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public RecursiveRadioGroup(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
super.addView(child, index, params);
|
||||
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;
|
||||
radioButtons.add(button);
|
||||
button.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (!isChecked) {
|
||||
return;
|
||||
}
|
||||
checkedButton = (RadioButton) buttonView;
|
||||
if (checkedChangeListener != null) {
|
||||
checkedChangeListener.onCheckedChanged(null, checkedButton.getId());
|
||||
}
|
||||
|
||||
for (RadioButton view : radioButtons) {
|
||||
if (view != buttonView) {
|
||||
view.setChecked(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (child instanceof ViewGroup) {
|
||||
parseChildren((ViewGroup) child);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseChildren(final ViewGroup child) {
|
||||
for (int i = 0; i < child.getChildCount(); i++) {
|
||||
parseChild(child.getChildAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public RadioButton getCheckedButton() {
|
||||
return checkedButton;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue