Reworked feed specific speed selector (#5458)

This commit is contained in:
ByteHamster 2021-10-10 11:10:23 +02:00 committed by GitHub
parent 5e0b95fa5c
commit 64b72d1ae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 177 additions and 172 deletions

View File

@ -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<String> audioTracks = controller.getAudioTracks();
int selectedAudioTrack = controller.getSelectedAudioTrack();

View File

@ -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));

View File

@ -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);

View File

@ -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() {

View File

@ -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<Float> 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<Float> 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);
}
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<CheckBox
android:id="@+id/useGlobalCheckbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/feed_auto_download_global"
android:layout_marginBottom="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<de.danoeh.antennapod.view.PlaybackSpeedSeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/currentSpeedLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" />
</LinearLayout>
</LinearLayout>

View File

@ -1,43 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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">
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">
<TextView
android:id="@+id/butDecSpeed"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:text="-"
android:clickable="true"
android:focusable="true"
android:textStyle="bold"
android:textSize="24sp"
android:textColor="?attr/colorSecondary"
android:contentDescription="@string/decrease_speed"
android:background="?attr/selectableItemBackgroundBorderless"/>
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" />
<SeekBar
android:id="@+id/playback_speed"
android:layout_width="0dp"
android:layout_height="32dp"
android:max="70"
android:layout_weight="1" />
android:id="@+id/playback_speed"
android:layout_width="0dp"
android:layout_height="32dp"
android:max="70"
android:layout_weight="1" />
<TextView
android:id="@+id/butIncSpeed"
android:layout_width="32dp"
android:layout_height="32dp"
android:gravity="center"
android:text="+"
android:clickable="true"
android:focusable="true"
android:textStyle="bold"
android:textSize="24sp"
android:textColor="?attr/colorSecondary"
android:contentDescription="@string/increase_speed"
android:background="?attr/selectableItemBackgroundBorderless" />
</LinearLayout>
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" />
</LinearLayout>

View File

@ -28,7 +28,7 @@
android:summary="@string/feed_tags_summary"
android:title="@string/feed_tags_label" />
<ListPreference
<Preference
android:icon="@drawable/ic_playback_speed"
android:key="feedPlaybackSpeed"
android:summary="@string/pref_feed_playback_speed_sum"

View File

@ -135,58 +135,6 @@
<item>-2</item>
</string-array>
<string-array name="playback_speed_values">
<item>0.50</item>
<item>0.60</item>
<item>0.70</item>
<item>0.75</item>
<item>0.80</item>
<item>0.85</item>
<item>0.90</item>
<item>0.95</item>
<item>1.00</item>
<item>1.05</item>
<item>1.10</item>
<item>1.15</item>
<item>1.20</item>
<item>1.25</item>
<item>1.30</item>
<item>1.35</item>
<item>1.40</item>
<item>1.45</item>
<item>1.50</item>
<item>1.55</item>
<item>1.60</item>
<item>1.65</item>
<item>1.70</item>
<item>1.75</item>
<item>1.80</item>
<item>1.85</item>
<item>1.90</item>
<item>1.95</item>
<item>2.00</item>
<item>2.10</item>
<item>2.20</item>
<item>2.30</item>
<item>2.40</item>
<item>2.50</item>
<item>2.60</item>
<item>2.70</item>
<item>2.80</item>
<item>2.90</item>
<item>3.00</item>
<item>3.10</item>
<item>3.20</item>
<item>3.30</item>
<item>3.40</item>
<item>3.50</item>
<item>3.60</item>
<item>3.70</item>
<item>3.80</item>
<item>3.90</item>
<item>4.00</item>
</string-array>
<string-array name="theme_options">
<item>@string/pref_theme_title_use_system</item>
<item>@string/pref_theme_title_light</item>