From 54612c6b74b50dca7ae8808ecc7dcae86947eb10 Mon Sep 17 00:00:00 2001 From: tiltshiftfocus Date: Mon, 9 Feb 2026 02:18:01 +0800 Subject: [PATCH] patch: Addressing some UI/UX quirks (#413) * beautify lyrics display * use dialog to select playback speed to prevent accidental clicks --- .../tempo/ui/dialog/PlaybackSpeedDialog.java | 57 +++++++++++++++++++ .../ui/fragment/PlayerControllerFragment.java | 14 ++--- .../ui/fragment/PlayerLyricsFragment.java | 6 +- .../layout/inner_fragment_player_lyrics.xml | 2 + app/src/main/res/values/strings.xml | 2 + 5 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaybackSpeedDialog.java diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaybackSpeedDialog.java b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaybackSpeedDialog.java new file mode 100644 index 00000000..decd2d3e --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaybackSpeedDialog.java @@ -0,0 +1,57 @@ +package com.cappielloantonio.tempo.ui.dialog; + +import android.app.Dialog; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + +import com.cappielloantonio.tempo.R; +import com.cappielloantonio.tempo.util.Preferences; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +public class PlaybackSpeedDialog extends DialogFragment { + private static final String TAG = "PlaybackSpeedDialog"; + + public interface PlaybackSpeedListener { + void onSpeedSelected(float speed); + } + + private PlaybackSpeedListener listener; + + private static final float[] SPEED_VALUES = {0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f}; + private static final String[] SPEED_LABELS = {"0.5x", "0.75x", "1.0x", "1.25x", "1.5x", "1.75x", "2.0x"}; + + public void setPlaybackSpeedListener(PlaybackSpeedListener listener) { + this.listener = listener; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + float currentSpeed = Preferences.getPlaybackSpeed(); + int selectedIndex = getSelectedIndex(currentSpeed); + + return new MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.playback_speed_dialog_title) + .setSingleChoiceItems(SPEED_LABELS, selectedIndex, (dialog, which) -> { + float selectedSpeed = SPEED_VALUES[which]; + Preferences.setPlaybackSpeed(selectedSpeed); + if (listener != null) { + listener.onSpeedSelected(selectedSpeed); + } + dialog.dismiss(); + }) + .setNegativeButton(R.string.playback_speed_dialog_negative_button, (dialog, id) -> dialog.cancel()) + .create(); + } + + private int getSelectedIndex(float currentSpeed) { + for (int i = 0; i < SPEED_VALUES.length; i++) { + if (Math.abs(SPEED_VALUES[i] - currentSpeed) < 0.01f) { + return i; + } + } + return 2; // Default to 1.0x + } +} diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java index f45b5061..c6a0d6fd 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java @@ -39,6 +39,7 @@ import com.cappielloantonio.tempo.databinding.InnerFragmentPlayerControllerBindi import com.cappielloantonio.tempo.service.EqualizerManager; import com.cappielloantonio.tempo.service.MediaService; import com.cappielloantonio.tempo.ui.activity.MainActivity; +import com.cappielloantonio.tempo.ui.dialog.PlaybackSpeedDialog; import com.cappielloantonio.tempo.ui.dialog.RatingDialog; import com.cappielloantonio.tempo.ui.dialog.TrackInfoDialog; import com.cappielloantonio.tempo.ui.fragment.pager.PlayerControllerHorizontalPager; @@ -522,13 +523,12 @@ public class PlayerControllerFragment extends Fragment { private void initPlaybackSpeedButton(MediaBrowser mediaBrowser) { playbackSpeedButton.setOnClickListener(view -> { - float currentSpeed = Preferences.getPlaybackSpeed(); - - currentSpeed += 0.25f; - if (currentSpeed > 2.0f) currentSpeed = 0.5f; - mediaBrowser.setPlaybackParameters(new PlaybackParameters(currentSpeed)); - playbackSpeedButton.setText(getString(R.string.player_playback_speed, currentSpeed)); - Preferences.setPlaybackSpeed(currentSpeed); + PlaybackSpeedDialog dialog = new PlaybackSpeedDialog(); + dialog.setPlaybackSpeedListener(speed -> { + mediaBrowser.setPlaybackParameters(new PlaybackParameters(speed)); + playbackSpeedButton.setText(getString(R.string.player_playback_speed, speed)); + }); + dialog.show(requireActivity().getSupportFragmentManager(), null); }); skipSilenceToggleButton.setOnClickListener(view -> { diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java index 20e420ea..6872bcd8 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java @@ -253,7 +253,7 @@ public class PlayerLyricsFragment extends Fragment { if (lines != null) { for (Line line : lines) { - lyricsBuilder.append(line.getValue().trim()).append("\n"); + lyricsBuilder.append(line.getValue().trim()).append("\n\n"); } } @@ -316,7 +316,7 @@ public class PlayerLyricsFragment extends Fragment { StringBuilder lyricsBuilder = new StringBuilder(); for (Line line : lines) { - lyricsBuilder.append(line.getValue().trim()).append("\n"); + lyricsBuilder.append(line.getValue().trim()).append("\n\n"); } String lyrics = lyricsBuilder.toString(); Spannable spannableString = new SpannableString(lyrics); @@ -328,7 +328,7 @@ public class PlayerLyricsFragment extends Fragment { boolean highlight = i == curIdx; if (highlight) highlightStart = offset; - int len = lines.get(i).getValue().length() + 1; + int len = lines.get(i).getValue().length() + 2; final int lineStart = lines.get(i).getStart(); spannableString.setSpan(new ClickableSpan() { @Override diff --git a/app/src/main/res/layout/inner_fragment_player_lyrics.xml b/app/src/main/res/layout/inner_fragment_player_lyrics.xml index 5ece8996..92449e11 100644 --- a/app/src/main/res/layout/inner_fragment_player_lyrics.xml +++ b/app/src/main/res/layout/inner_fragment_player_lyrics.xml @@ -46,6 +46,8 @@ style="@style/BodyLarge" android:layout_width="match_parent" android:layout_height="match_parent" + android:gravity="center_horizontal" + android:lineSpacingExtra="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 311588a8..87edad2b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -217,6 +217,8 @@ Remove from home screen Year %1$.2fx + Playback Speed + Cancel Clean play queue Saved play queue Save Queue to Playlist