feat: improve playlist chooser dialog UI (#439)

* fix: lock buttons at dialog bottom

The previous implementation appended the buttons to the RecyclerView programmatically
this disabled the scroll and pushed the buttons outside the visible dialog area
if too there were too many playlists.

To fix this now the XML defines a fixed location for the buttons, enabling
the scroll of the RecyclerView and preventing the buttons to become unreachable

* feat: improve playlist chooser dialog UI

Implement it in the XML layout and not programmatically.

* fix: detached listeners from XML layout

* fix: missing dialog title
This commit is contained in:
Tom 2026-02-15 14:42:07 -03:00 committed by GitHub
parent 661346ca3a
commit 9adaf8c013
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 101 additions and 59 deletions

View file

@ -6,7 +6,6 @@ import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -20,41 +19,30 @@ import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.viewmodel.PlaylistChooserViewModel;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
public class PlaylistChooserDialog extends DialogFragment implements ClickCallback {
private DialogPlaylistChooserBinding bind;
private PlaylistChooserViewModel playlistChooserViewModel;
private PlaylistDialogHorizontalAdapter playlistDialogHorizontalAdapter;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
DialogPlaylistChooserBinding.inflate(getLayoutInflater());
bind = DialogPlaylistChooserBinding.inflate(getLayoutInflater());
playlistChooserViewModel = new ViewModelProvider(requireActivity()).get(PlaylistChooserViewModel.class);
String[] playlistVisibilityChoice = {
getString(R.string.playlist_chooser_dialog_visibility_public),
getString(R.string.playlist_chooser_dialog_visibility_private)
};
bind.playlistDialogChooserVisibilitySwitch.setOnCheckedChangeListener(
(buttonView,
isChecked) -> playlistChooserViewModel.setIsPlaylistPublic(isChecked)
);
bind.playlistChooserDialogCreateButton.setOnClickListener(v -> launchPlaylistEditor());
bind.playlistChooserDialogCancelButton.setOnClickListener(v -> dismiss());
return new MaterialAlertDialogBuilder(getActivity())
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext())
.setView(bind.getRoot())
.setTitle(R.string.playlist_chooser_dialog_title)
.setSingleChoiceItems(
playlistVisibilityChoice,
0,
(dialog, which) -> {
boolean isPublic = (which == 0);
playlistChooserViewModel.setIsPlaylistPublic(isPublic);
})
.setNeutralButton(R.string.playlist_chooser_dialog_neutral_button, (dialog, id) -> { })
.setNegativeButton(R.string.playlist_chooser_dialog_negative_button, (dialog, id) -> dialog.cancel())
.create();
.setTitle(R.string.playlist_chooser_dialog_title);
return builder.create();
}
@Override
@ -69,25 +57,26 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba
initPlaylistView();
setSongInfo();
setButtonAction();
}
private void setSongInfo() {
playlistChooserViewModel.setSongsToAdd(requireArguments().getParcelableArrayList(Constants.TRACKS_OBJECT));
}
private void setButtonAction() {
androidx.appcompat.app.AlertDialog alertDialog = (androidx.appcompat.app.AlertDialog) Objects.requireNonNull(getDialog());
alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, playlistChooserViewModel.getSongsToAdd());
private void launchPlaylistEditor() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(
Constants.TRACKS_OBJECT,
playlistChooserViewModel.getSongsToAdd()
);
PlaylistEditorDialog dialog = new PlaylistEditorDialog(null);
dialog.setArguments(bundle);
dialog.show(requireActivity().getSupportFragmentManager(), null);
PlaylistEditorDialog editorDialog = new PlaylistEditorDialog(null);
editorDialog.setArguments(bundle);
editorDialog.show(
requireActivity().getSupportFragmentManager(),
null);
Objects.requireNonNull(getDialog()).dismiss();
});
dismiss();
}
private void initPlaylistView() {

View file

@ -3,6 +3,26 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/playlist_dialog_chooser_visibility_switch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingStart="30dp"
android:paddingEnd="30dp"
android:checked="false"
android:showText="false"
android:text="@string/playlist_chooser_dialog_visibility_switch_label" />
<TextView
android:id="@+id/playlist_dialog_chooser_visibility_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="30dp"
android:paddingEnd="30dp"
android:text="@string/playlist_chooser_dialog_visibility_summary"
android:layout_marginTop="8dp"/>
<TextView
android:id="@+id/no_playlists_created_text_view"
style="@style/TitleMedium"
@ -23,4 +43,35 @@
android:layout_weight="1"
android:layout_marginTop="8dp"
android:clipToPadding="false" />
<LinearLayout
android:id="@+id/button_bar"
style="?android:attr/buttonBarStyle"
android:orientation="horizontal"
android:gravity="bottom|center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2"
android:layout_marginTop="16dp">
<Button
android:id="@+id/playlist_chooser_dialog_create_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="start"
android:text="@string/playlist_chooser_dialog_create_button" />
<Button
android:id="@+id/playlist_chooser_dialog_cancel_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:layout_gravity="end"
android:text="@string/playlist_chooser_dialog_cancel_button"/>
</LinearLayout>
</LinearLayout>

View file

@ -224,8 +224,8 @@
<string name="playlist_catalogue_title">Catàleg de llistes de reproducció</string>
<string name="playlist_catalogue_title_expanded">Exploració de llistes de reproducció</string>
<string name="playlist_chooser_dialog_empty">No s\'ha creat cap llista de reproducció</string>
<string name="playlist_chooser_dialog_negative_button">Cancel·la</string>
<string name="playlist_chooser_dialog_neutral_button">Crea</string>
<string name="playlist_chooser_dialog_cancel_button">Cancel·la</string>
<string name="playlist_chooser_dialog_create_button">Crea</string>
<string name="playlist_chooser_dialog_title">Addició a una llista de reproducció</string>
<string name="playlist_chooser_dialog_toast_add_success">S\'han afegit les cançons a la llista de reproducció</string>
<string name="playlist_chooser_dialog_toast_add_failure">No s\'han pogut afegir les cançons a la llista de reproducció</string>

View file

@ -188,8 +188,8 @@
<string name="playlist_catalogue_title">Playlisten</string>
<string name="playlist_catalogue_title_expanded">Playlisten durchsuchen</string>
<string name="playlist_chooser_dialog_empty">Keine Playlisten erstellt</string>
<string name="playlist_chooser_dialog_negative_button">Abbrechen</string>
<string name="playlist_chooser_dialog_neutral_button">Erstellen</string>
<string name="playlist_chooser_dialog_cancel_button">Abbrechen</string>
<string name="playlist_chooser_dialog_create_button">Erstellen</string>
<string name="playlist_chooser_dialog_title">Zu einer Playliste hinzufügen</string>
<string name="playlist_chooser_dialog_toast_add_success">Lied zu Playlist hinzugefügt</string>
<string name="playlist_chooser_dialog_toast_add_failure">Titel kann nicht zur Playlist hinzugefügt werden</string>

View file

@ -223,8 +223,8 @@
<string name="playlist_catalogue_title">Catálogo de listas de reproducción</string>
<string name="playlist_catalogue_title_expanded">Explorar listas de reproducción</string>
<string name="playlist_chooser_dialog_empty">No hay listas de reproducción</string>
<string name="playlist_chooser_dialog_negative_button">Cancelar</string>
<string name="playlist_chooser_dialog_neutral_button">Crear</string>
<string name="playlist_chooser_dialog_cancel_button">Cancelar</string>
<string name="playlist_chooser_dialog_create_button">Crear</string>
<string name="playlist_chooser_dialog_title">Añadir a una lista de reproducción</string>
<string name="playlist_chooser_dialog_toast_add_failure">Error al añadir a la lista</string>
<string name="playlist_chooser_dialog_toast_all_skipped">Todas las pistas se han descartado porque están repetidas</string>

View file

@ -230,8 +230,8 @@
<string name="playlist_catalogue_title">Catalogue des Playlists</string>
<string name="playlist_catalogue_title_expanded">Parcourir les playlists</string>
<string name="playlist_chooser_dialog_empty">Pas de playlist</string>
<string name="playlist_chooser_dialog_negative_button">Annuler</string>
<string name="playlist_chooser_dialog_neutral_button">Créer</string>
<string name="playlist_chooser_dialog_cancel_button">Annuler</string>
<string name="playlist_chooser_dialog_create_button">Créer</string>
<string name="playlist_chooser_dialog_title">Ajouter à une playlist</string>
<string name="playlist_chooser_dialog_toast_add_success">Titre ajouté à la playlist</string>
<string name="playlist_chooser_dialog_toast_add_failure">Échec d\'ajout du titre à la playlist</string>

View file

@ -223,8 +223,8 @@
<string name="playlist_catalogue_title">Catalogo playlist</string>
<string name="playlist_catalogue_title_expanded">Sfoglia le playlist</string>
<string name="playlist_chooser_dialog_empty">Nessuna playlist creata</string>
<string name="playlist_chooser_dialog_negative_button">Annulla</string>
<string name="playlist_chooser_dialog_neutral_button">Crea</string>
<string name="playlist_chooser_dialog_cancel_button">Annulla</string>
<string name="playlist_chooser_dialog_create_button">Crea</string>
<string name="playlist_chooser_dialog_title">Aggiungi a una playlist</string>
<string name="playlist_chooser_dialog_toast_add_success">Aggiunta di un brano alla playlist</string>
<string name="playlist_chooser_dialog_toast_add_failure">Impossibile aggiungere un brano alla playlist</string>

View file

@ -172,8 +172,8 @@
<string name="playlist_catalogue_title">플레이리스트 카탈로그</string>
<string name="playlist_catalogue_title_expanded">플레이리스트 찾아보기</string>
<string name="playlist_chooser_dialog_empty">플레이리스트가 없습니다.</string>
<string name="playlist_chooser_dialog_negative_button">취소</string>
<string name="playlist_chooser_dialog_neutral_button">생성</string>
<string name="playlist_chooser_dialog_cancel_button">취소</string>
<string name="playlist_chooser_dialog_create_button">생성</string>
<string name="playlist_chooser_dialog_title">플레이리스트 추가</string>
<string name="playlist_chooser_dialog_toast_add_success">재생 목록에 음악 추가</string>
<string name="playlist_chooser_dialog_toast_add_failure">재생 목록에 음악을 추가하지 못했습니다.</string>

View file

@ -222,8 +222,8 @@
<string name="playlist_catalogue_title">Katalog Playlist</string>
<string name="playlist_catalogue_title_expanded">Przeglądaj Playlisty</string>
<string name="playlist_chooser_dialog_empty">Nie utworzono playlist</string>
<string name="playlist_chooser_dialog_negative_button">Anuluj</string>
<string name="playlist_chooser_dialog_neutral_button">Utwórz</string>
<string name="playlist_chooser_dialog_cancel_button">Anuluj</string>
<string name="playlist_chooser_dialog_create_button">Utwórz</string>
<string name="playlist_chooser_dialog_title">Dodaj do playlisty</string>
<string name="playlist_chooser_dialog_toast_add_success">Dodano piosenki do playlisty</string>
<string name="playlist_chooser_dialog_toast_add_failure">Nie udało się dodać piosenek do playlisty</string>

View file

@ -159,8 +159,8 @@
<string name="playlist_catalogue_title">Catálogo de Playlists</string>
<string name="playlist_catalogue_title_expanded">Navegar pelas Playlists</string>
<string name="playlist_chooser_dialog_empty">Nenhuma playlist criada</string>
<string name="playlist_chooser_dialog_negative_button">Cancelar</string>
<string name="playlist_chooser_dialog_neutral_button">Criar</string>
<string name="playlist_chooser_dialog_cancel_button">Cancelar</string>
<string name="playlist_chooser_dialog_create_button">Criar</string>
<string name="playlist_chooser_dialog_title">Adicionar a uma playlist</string>
<string name="playlist_chooser_dialog_toast_add_success">Adicionada playlist de reprodução</string>
<string name="playlist_chooser_dialog_toast_add_failure">Falha ao adicionar uma playlist de reprodução</string>

View file

@ -233,8 +233,8 @@
<string name="playlist_catalogue_title">Catalogul Playlisturi</string>
<string name="playlist_catalogue_title_expanded">Răsfoiți Playlisturi</string>
<string name="playlist_chooser_dialog_empty">Niciun playlist creat</string>
<string name="playlist_chooser_dialog_negative_button">Anulati</string>
<string name="playlist_chooser_dialog_neutral_button">Creaţi</string>
<string name="playlist_chooser_dialog_cancel_button">Anulati</string>
<string name="playlist_chooser_dialog_create_button">Creaţi</string>
<string name="playlist_chooser_dialog_title">Adăugați la un playlist</string>
<string name="playlist_chooser_dialog_toast_add_success">Piesa(e) adăugată(e) la playlist</string>
<string name="playlist_chooser_dialog_toast_add_failure">Eșec la adăugarea piese(lor) la playlist</string>

View file

@ -200,8 +200,8 @@
<string name="playlist_catalogue_title">Каталог плейлистов</string>
<string name="playlist_catalogue_title_expanded">Просмотр плейлистов</string>
<string name="playlist_chooser_dialog_empty">Плейлисты не созданы</string>
<string name="playlist_chooser_dialog_negative_button">Отмена</string>
<string name="playlist_chooser_dialog_neutral_button">Создать</string>
<string name="playlist_chooser_dialog_cancel_button">Отмена</string>
<string name="playlist_chooser_dialog_create_button">Создать</string>
<string name="playlist_chooser_dialog_title">Добавить в плейлист</string>
<string name="playlist_chooser_dialog_toast_add_success">Добавьте песню в плейлист</string>
<string name="playlist_chooser_dialog_toast_add_failure">Не удалось добавить песню в список воспроизведения</string>

View file

@ -203,8 +203,8 @@
<string name="playlist_catalogue_title">Çalma Listesi Kataloğu</string>
<string name="playlist_catalogue_title_expanded">Çalma listelerine göz at</string>
<string name="playlist_chooser_dialog_empty">Henüz çalma listesi oluşturulmadı</string>
<string name="playlist_chooser_dialog_negative_button">İptal</string>
<string name="playlist_chooser_dialog_neutral_button">Oluştur</string>
<string name="playlist_chooser_dialog_cancel_button">İptal</string>
<string name="playlist_chooser_dialog_create_button">Oluştur</string>
<string name="playlist_chooser_dialog_title">Çalma listesine ekle</string>
<string name="playlist_chooser_dialog_toast_add_success">Şarkı çalma listesine eklendi</string>
<string name="playlist_chooser_dialog_toast_add_failure">Şarkı çalma listesine eklenemedi</string>

View file

@ -260,8 +260,8 @@
<string name="playlist_catalogue_title">播放列表目录</string>
<string name="playlist_catalogue_title_expanded">浏览播放列表</string>
<string name="playlist_chooser_dialog_empty">尚未创建播放列表</string>
<string name="playlist_chooser_dialog_negative_button">取消</string>
<string name="playlist_chooser_dialog_neutral_button">新建</string>
<string name="playlist_chooser_dialog_cancel_button">取消</string>
<string name="playlist_chooser_dialog_create_button">新建</string>
<string name="playlist_chooser_dialog_title">添加到播放列表</string>
<string name="playlist_chooser_dialog_toast_add_failure">未能将歌曲添加到播放列表</string>
<string name="playlist_chooser_dialog_toast_add_success">将歌曲添加到播放列表</string>

View file

@ -234,14 +234,16 @@
<string name="playlist_catalogue_title">Playlist Catalogue</string>
<string name="playlist_catalogue_title_expanded">Browse Playlists</string>
<string name="playlist_chooser_dialog_empty">No playlists created</string>
<string name="playlist_chooser_dialog_negative_button">Cancel</string>
<string name="playlist_chooser_dialog_neutral_button">Create</string>
<string name="playlist_chooser_dialog_cancel_button">Cancel</string>
<string name="playlist_chooser_dialog_create_button">Create</string>
<string name="playlist_chooser_dialog_title">Add to a playlist</string>
<string name="playlist_chooser_dialog_toast_add_success">Added song(s) to playlist</string>
<string name="playlist_chooser_dialog_toast_add_failure">Failed to add song(s) to playlist</string>
<string name="playlist_chooser_dialog_toast_all_skipped">All songs were skipped as duplicates</string>
<string name="playlist_chooser_dialog_visibility_public">Public</string>
<string name="playlist_chooser_dialog_visibility_private">Private</string>
<string name="playlist_chooser_dialog_visibility_switch_label">Mark the playlist as public</string>
<string name="playlist_chooser_dialog_visibility_summary">The server updates the visibility on each request. By default it is set to private.</string>
<string name="playlist_counted_tracks">%1$d tracks • %2$s</string>
<string name="playlist_duration">Duration • %1$s</string>
<string name="playlist_editor_dialog_action_delete_toast">Long press to delete</string>