From 64b72d1ae95402da73a5f1a66995d43b8fd65ce5 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 10 Oct 2021 11:10:23 +0200 Subject: [PATCH] Reworked feed specific speed selector (#5458) --- .../dialog/PlaybackControlsDialog.java | 31 ++++++-- .../dialog/VariableSpeedDialog.java | 9 ++- .../fragment/FeedSettingsFragment.java | 66 ++++++++--------- .../actions/FeedMultiSelectActionHandler.java | 39 +++++----- .../antennapod/view/PlaybackSpeedSeekBar.java | 40 +++++----- .../playback_speed_feed_setting_dialog.xml | 37 ++++++++++ .../res/layout/playback_speed_seek_bar.xml | 73 ++++++++++--------- app/src/main/res/xml/feed_settings.xml | 2 +- core/src/main/res/values/arrays.xml | 52 ------------- 9 files changed, 177 insertions(+), 172 deletions(-) create mode 100644 app/src/main/res/layout/playback_speed_feed_setting_dialog.xml diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java index 3186cbe2e..31c2d3369 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java @@ -22,6 +22,8 @@ import java.util.Locale; public class PlaybackControlsDialog extends DialogFragment { private PlaybackController controller; private AlertDialog dialog; + private PlaybackSpeedSeekBar speedSeekBar; + private TextView txtvPlaybackSpeed; public static PlaybackControlsDialog newInstance() { Bundle arguments = new Bundle(); @@ -42,6 +44,12 @@ public class PlaybackControlsDialog extends DialogFragment { public void loadMediaInfo() { setupUi(); setupAudioTracks(); + updateSpeed(); + } + + @Override + public void onPlaybackSpeedChange() { + updateSpeed(); } }; controller.init(); @@ -66,12 +74,15 @@ public class PlaybackControlsDialog extends DialogFragment { } private void setupUi() { - final TextView txtvPlaybackSpeed = dialog.findViewById(R.id.txtvPlaybackSpeed); - - PlaybackSpeedSeekBar speedSeekBar = dialog.findViewById(R.id.speed_seek_bar); - speedSeekBar.setController(controller); - speedSeekBar.setProgressChangedListener(speed - -> txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", speed))); + txtvPlaybackSpeed = dialog.findViewById(R.id.txtvPlaybackSpeed); + speedSeekBar = dialog.findViewById(R.id.speed_seek_bar); + speedSeekBar.setProgressChangedListener(speed -> { + if (controller != null) { + controller.setPlaybackSpeed(speed); + updateSpeed(); + } + }); + updateSpeed(); final CheckBox stereoToMono = dialog.findViewById(R.id.stereo_to_mono); stereoToMono.setChecked(UserPreferences.stereoToMono()); @@ -100,6 +111,14 @@ public class PlaybackControlsDialog extends DialogFragment { }); } + private void updateSpeed() { + if (controller != null) { + txtvPlaybackSpeed.setText(String.format( + Locale.getDefault(), "%.2fx", controller.getCurrentPlaybackSpeedMultiplier())); + speedSeekBar.updateSpeed(controller.getCurrentPlaybackSpeedMultiplier()); + } + } + private void setupAudioTracks() { List audioTracks = controller.getAudioTracks(); int selectedAudioTrack = controller.getSelectedAudioTrack(); diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java index 6011872cf..dffd49c45 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java @@ -55,11 +55,11 @@ public class VariableSpeedDialog extends DialogFragment { } }; controller.init(); - speedSeekBar.setController(controller); + updateSpeed(); } private void updateSpeed() { - speedSeekBar.updateSpeed(); + speedSeekBar.updateSpeed(controller.getCurrentPlaybackSpeedMultiplier()); addCurrentSpeedChip.setText(speedFormat.format(controller.getCurrentPlaybackSpeedMultiplier())); } @@ -78,6 +78,11 @@ public class VariableSpeedDialog extends DialogFragment { View root = View.inflate(getContext(), R.layout.speed_select_dialog, null); speedSeekBar = root.findViewById(R.id.speed_seek_bar); + speedSeekBar.setProgressChangedListener(multiplier -> { + if (controller != null) { + controller.setPlaybackSpeed(multiplier); + } + }); RecyclerView selectedSpeedsGrid = root.findViewById(R.id.selected_speeds_grid); selectedSpeedsGrid.setLayoutManager(new GridLayoutManager(getContext(), 3)); selectedSpeedsGrid.addItemDecoration(new ItemOffsetDecoration(getContext(), 4)); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java index dbc7f2ae3..5bd1dbb20 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java @@ -7,9 +7,11 @@ import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.preference.ListPreference; +import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.SwitchPreferenceCompat; import androidx.recyclerview.widget.RecyclerView; @@ -17,6 +19,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.event.settings.SkipIntroEndingChangedEvent; import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent; import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent; +import de.danoeh.antennapod.databinding.PlaybackSpeedFeedSettingDialogBinding; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedFilter; import de.danoeh.antennapod.model.feed.FeedPreferences; @@ -35,12 +38,8 @@ import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import org.greenrobot.eventbus.EventBus; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.util.Locale; -import static de.danoeh.antennapod.model.feed.FeedPreferences.SPEED_USE_GLOBAL; - public class FeedSettingsFragment extends Fragment { private static final String TAG = "FeedSettingsFragment"; private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId"; @@ -104,8 +103,6 @@ public class FeedSettingsFragment extends Fragment { private static final String PREF_FEED_PLAYBACK_SPEED = "feedPlaybackSpeed"; private static final String PREF_AUTO_SKIP = "feedAutoSkip"; private static final String PREF_TAGS = "tags"; - private static final DecimalFormat SPEED_FORMAT = - new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US)); private Feed feed; private Disposable disposable; @@ -164,7 +161,6 @@ public class FeedSettingsFragment extends Fragment { updateAutoDeleteSummary(); updateVolumeReductionValue(); updateAutoDownloadEnabled(); - updatePlaybackSpeedPreference(); if (feed.isLocalFeed()) { findPreference(PREF_AUTHENTICATION).setVisible(false); @@ -205,27 +201,34 @@ public class FeedSettingsFragment extends Fragment { } private void setupPlaybackSpeedPreference() { - ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED); - - final String[] speeds = getResources().getStringArray(R.array.playback_speed_values); - String[] values = new String[speeds.length + 1]; - values[0] = SPEED_FORMAT.format(SPEED_USE_GLOBAL); - - String[] entries = new String[speeds.length + 1]; - entries[0] = getString(R.string.feed_auto_download_global); - - System.arraycopy(speeds, 0, values, 1, speeds.length); - System.arraycopy(speeds, 0, entries, 1, speeds.length); - - feedPlaybackSpeedPreference.setEntryValues(values); - feedPlaybackSpeedPreference.setEntries(entries); - feedPlaybackSpeedPreference.setOnPreferenceChangeListener((preference, newValue) -> { - feedPreferences.setFeedPlaybackSpeed(Float.parseFloat((String) newValue)); - DBWriter.setFeedPreferences(feedPreferences); - updatePlaybackSpeedPreference(); - EventBus.getDefault().post( - new SpeedPresetChangedEvent(feedPreferences.getFeedPlaybackSpeed(), feed.getId())); - return false; + Preference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED); + feedPlaybackSpeedPreference.setOnPreferenceClickListener(preference -> { + PlaybackSpeedFeedSettingDialogBinding viewBinding = + PlaybackSpeedFeedSettingDialogBinding.inflate(getLayoutInflater()); + viewBinding.seekBar.setProgressChangedListener(speed -> + viewBinding.currentSpeedLabel.setText(String.format(Locale.getDefault(), "%.2fx", speed))); + float speed = feedPreferences.getFeedPlaybackSpeed(); + viewBinding.useGlobalCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + viewBinding.seekBar.setEnabled(!isChecked); + viewBinding.seekBar.setAlpha(isChecked ? 0.4f : 1f); + viewBinding.currentSpeedLabel.setAlpha(isChecked ? 0.4f : 1f); + }); + viewBinding.useGlobalCheckbox.setChecked(speed == FeedPreferences.SPEED_USE_GLOBAL); + viewBinding.seekBar.updateSpeed(speed == FeedPreferences.SPEED_USE_GLOBAL ? 1 : speed); + new AlertDialog.Builder(getContext()) + .setTitle(R.string.playback_speed) + .setView(viewBinding.getRoot()) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + float newSpeed = viewBinding.useGlobalCheckbox.isChecked() + ? FeedPreferences.SPEED_USE_GLOBAL : viewBinding.seekBar.getCurrentSpeed(); + feedPreferences.setFeedPlaybackSpeed(newSpeed); + DBWriter.setFeedPreferences(feedPreferences); + EventBus.getDefault().post( + new SpeedPresetChangedEvent(feedPreferences.getFeedPlaybackSpeed(), feed.getId())); + }) + .setNegativeButton(R.string.cancel_label, null) + .show(); + return true; }); } @@ -277,13 +280,6 @@ public class FeedSettingsFragment extends Fragment { }); } - private void updatePlaybackSpeedPreference() { - ListPreference feedPlaybackSpeedPreference = findPreference(PREF_FEED_PLAYBACK_SPEED); - - float speedValue = feedPreferences.getFeedPlaybackSpeed(); - feedPlaybackSpeedPreference.setValue(SPEED_FORMAT.format(speedValue)); - } - private void updateAutoDeleteSummary() { ListPreference autoDeletePreference = findPreference(PREF_AUTO_DELETE); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java b/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java index f160b2241..36df74347 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.fragment.actions; import android.util.Log; import androidx.annotation.PluralsRes; +import androidx.appcompat.app.AlertDialog; import androidx.core.util.Consumer; import com.google.android.material.snackbar.Snackbar; @@ -15,6 +16,7 @@ import java.util.Locale; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.databinding.PlaybackSpeedFeedSettingDialogBinding; import de.danoeh.antennapod.dialog.RemoveFeedDialog; import de.danoeh.antennapod.fragment.preferences.dialog.PreferenceListDialog; import de.danoeh.antennapod.fragment.preferences.dialog.PreferenceSwitchDialog; @@ -64,25 +66,26 @@ public class FeedMultiSelectActionHandler { new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US)); private void playbackSpeedPrefHandler() { - final String[] speeds = activity.getResources().getStringArray(R.array.playback_speed_values); - String[] values = new String[speeds.length + 1]; - values[0] = SPEED_FORMAT.format(FeedPreferences.SPEED_USE_GLOBAL); - - String[] entries = new String[speeds.length + 1]; - entries[0] = activity.getString(R.string.feed_auto_download_global); - - System.arraycopy(speeds, 0, values, 1, speeds.length); - System.arraycopy(speeds, 0, entries, 1, speeds.length); - - PreferenceListDialog preferenceListDialog = new PreferenceListDialog(activity, - activity.getString(R.string.playback_speed)); - preferenceListDialog.openDialog(entries); - preferenceListDialog.setOnPreferenceChangedListener(pos -> { - saveFeedPreferences(feedPreferences -> { - feedPreferences.setFeedPlaybackSpeed(Float.parseFloat((String) values[pos])); - }); - + PlaybackSpeedFeedSettingDialogBinding viewBinding = + PlaybackSpeedFeedSettingDialogBinding.inflate(activity.getLayoutInflater()); + viewBinding.seekBar.setProgressChangedListener(speed -> + viewBinding.currentSpeedLabel.setText(String.format(Locale.getDefault(), "%.2fx", speed))); + viewBinding.useGlobalCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + viewBinding.seekBar.setEnabled(!isChecked); + viewBinding.seekBar.setAlpha(isChecked ? 0.4f : 1f); + viewBinding.currentSpeedLabel.setAlpha(isChecked ? 0.4f : 1f); }); + viewBinding.seekBar.updateSpeed(1.0f); + new AlertDialog.Builder(activity) + .setTitle(R.string.playback_speed) + .setView(viewBinding.getRoot()) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + float newSpeed = viewBinding.useGlobalCheckbox.isChecked() + ? FeedPreferences.SPEED_USE_GLOBAL : viewBinding.seekBar.getCurrentSpeed(); + saveFeedPreferences(feedPreferences -> feedPreferences.setFeedPlaybackSpeed(newSpeed)); + }) + .setNegativeButton(R.string.cancel_label, null) + .show(); } private void autoDeleteEpisodesPrefHandler() { diff --git a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java index c75164a74..33f0d47b8 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java +++ b/app/src/main/java/de/danoeh/antennapod/view/PlaybackSpeedSeekBar.java @@ -9,11 +9,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.util.Consumer; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.util.playback.PlaybackController; public class PlaybackSpeedSeekBar extends FrameLayout { private SeekBar seekBar; - private PlaybackController controller; private Consumer progressChangedListener; public PlaybackSpeedSeekBar(@NonNull Context context) { @@ -40,15 +38,9 @@ public class PlaybackSpeedSeekBar extends FrameLayout { seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (controller != null) { - float playbackSpeed = (progress + 10) / 20.0f; - controller.setPlaybackSpeed(playbackSpeed); - - if (progressChangedListener != null) { - progressChangedListener.accept(playbackSpeed); - } - } else if (fromUser) { - seekBar.post(() -> updateSpeed()); + float playbackSpeed = (progress + 10) / 20.0f; + if (progressChangedListener != null) { + progressChangedListener.accept(playbackSpeed); } } @@ -62,21 +54,23 @@ public class PlaybackSpeedSeekBar extends FrameLayout { }); } - public void updateSpeed() { - if (controller != null) { - seekBar.setProgress(Math.round((20 * controller.getCurrentPlaybackSpeedMultiplier()) - 10)); - } - } - - public void setController(PlaybackController controller) { - this.controller = controller; - updateSpeed(); - if (progressChangedListener != null && controller != null) { - progressChangedListener.accept(controller.getCurrentPlaybackSpeedMultiplier()); - } + public void updateSpeed(float speedMultiplier) { + seekBar.setProgress(Math.round((20 * speedMultiplier) - 10)); } public void setProgressChangedListener(Consumer progressChangedListener) { this.progressChangedListener = progressChangedListener; } + + public float getCurrentSpeed() { + return (seekBar.getProgress() + 10) / 20.0f; + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + seekBar.setEnabled(enabled); + findViewById(R.id.butDecSpeed).setEnabled(enabled); + findViewById(R.id.butIncSpeed).setEnabled(enabled); + } } diff --git a/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml b/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml new file mode 100644 index 000000000..572096911 --- /dev/null +++ b/app/src/main/res/layout/playback_speed_feed_setting_dialog.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/playback_speed_seek_bar.xml b/app/src/main/res/layout/playback_speed_seek_bar.xml index 0d3985f5a..c6feda030 100644 --- a/app/src/main/res/layout/playback_speed_seek_bar.xml +++ b/app/src/main/res/layout/playback_speed_seek_bar.xml @@ -1,43 +1,46 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center_vertical"> + android:id="@+id/butDecSpeed" + android:layout_width="32dp" + android:layout_height="32dp" + android:gravity="center" + android:text="-" + android:clickable="true" + android:focusable="true" + android:scrollbars="none" + android:textStyle="bold" + android:textSize="24sp" + android:textColor="?attr/colorSecondary" + android:contentDescription="@string/decrease_speed" + android:background="?attr/selectableItemBackgroundBorderless" /> + android:id="@+id/playback_speed" + android:layout_width="0dp" + android:layout_height="32dp" + android:max="70" + android:layout_weight="1" /> - \ No newline at end of file + android:id="@+id/butIncSpeed" + android:layout_width="32dp" + android:layout_height="32dp" + android:gravity="center" + android:text="+" + android:clickable="true" + android:focusable="true" + android:scrollbars="none" + android:textStyle="bold" + android:textSize="24sp" + android:textColor="?attr/colorSecondary" + android:contentDescription="@string/increase_speed" + android:background="?attr/selectableItemBackgroundBorderless" /> + + diff --git a/app/src/main/res/xml/feed_settings.xml b/app/src/main/res/xml/feed_settings.xml index 5b81ddd54..007f084c9 100644 --- a/app/src/main/res/xml/feed_settings.xml +++ b/app/src/main/res/xml/feed_settings.xml @@ -28,7 +28,7 @@ android:summary="@string/feed_tags_summary" android:title="@string/feed_tags_label" /> - -2 - - 0.50 - 0.60 - 0.70 - 0.75 - 0.80 - 0.85 - 0.90 - 0.95 - 1.00 - 1.05 - 1.10 - 1.15 - 1.20 - 1.25 - 1.30 - 1.35 - 1.40 - 1.45 - 1.50 - 1.55 - 1.60 - 1.65 - 1.70 - 1.75 - 1.80 - 1.85 - 1.90 - 1.95 - 2.00 - 2.10 - 2.20 - 2.30 - 2.40 - 2.50 - 2.60 - 2.70 - 2.80 - 2.90 - 3.00 - 3.10 - 3.20 - 3.30 - 3.40 - 3.50 - 3.60 - 3.70 - 3.80 - 3.90 - 4.00 - - @string/pref_theme_title_use_system @string/pref_theme_title_light