style: refined the design of favorite and rating indicators

This commit is contained in:
CappielloAntonio 2024-03-24 18:50:05 +01:00
parent 58d540b939
commit ff6bf20c30
14 changed files with 203 additions and 48 deletions

View file

@ -2,9 +2,11 @@ package com.cappielloantonio.tempo.ui.adapter;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.media3.session.MediaBrowser;
import androidx.recyclerview.widget.RecyclerView;
@ -17,6 +19,7 @@ import com.cappielloantonio.tempo.service.MediaManager;
import com.cappielloantonio.tempo.subsonic.models.Child;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil;
import com.cappielloantonio.tempo.util.Preferences;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
@ -66,12 +69,33 @@ public class PlayerSongQueueAdapter extends RecyclerView.Adapter<PlayerSongQueue
if (position < index) {
holder.item.queueSongTitleTextView.setAlpha(0.2f);
holder.item.queueSongSubtitleTextView.setAlpha(0.2f);
holder.item.ratingIndicatorImageView.setAlpha(0.2f);
} else {
holder.item.queueSongTitleTextView.setAlpha(1.0f);
holder.item.queueSongSubtitleTextView.setAlpha(1.0f);
holder.item.ratingIndicatorImageView.setAlpha(1.0f);
}
}
});
if (Preferences.showItemRating()) {
if (song.getStarred() == null && song.getUserRating() == null) {
holder.item.ratingIndicatorImageView.setVisibility(View.GONE);
}
holder.item.preferredIcon.setVisibility(song.getStarred() != null ? View.VISIBLE : View.GONE);
holder.item.ratingBarLayout.setVisibility(song.getUserRating() != null ? View.VISIBLE : View.GONE);
if (song.getUserRating() != null) {
holder.item.oneStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 1 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.twoStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 2 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.threeStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 3 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.fourStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 4 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.fiveStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 5 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
}
} else {
holder.item.ratingIndicatorImageView.setVisibility(View.GONE);
}
}
public List<Child> getItems() {

View file

@ -6,6 +6,7 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.media3.common.util.UnstableApi;
import androidx.recyclerview.widget.RecyclerView;
@ -60,13 +61,11 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
song.getArtist()
),
MusicUtil.getReadableDurationString(song.getDuration(), false),
MusicUtil.getReadableAudioQualityString(song),
MusicUtil.getRatingNumber(song.getUserRating())
MusicUtil.getReadableAudioQualityString(song)
)
);
holder.item.trackNumberTextView.setText(MusicUtil.getReadableTrackNumber(holder.itemView.getContext(), song.getTrack()));
if (Preferences.showItemRating()) holder.item.preferredIcon.setVisibility(song.getStarred() != null ? View.VISIBLE : View.GONE);
if (DownloadUtil.getDownloadTracker(holder.itemView.getContext()).isDownloaded(song.getId())) {
holder.item.searchResultDownloadIndicatorImageView.setVisibility(View.VISIBLE);
@ -85,6 +84,25 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
if (!showCoverArt && (position > 0 && songs.get(position - 1) != null && songs.get(position - 1).getDiscNumber() != null && songs.get(position).getDiscNumber() != null && songs.get(position - 1).getDiscNumber() < songs.get(position).getDiscNumber())) {
holder.item.differentDiskDivider.setVisibility(View.VISIBLE);
}
if (Preferences.showItemRating()) {
if (song.getStarred() == null && song.getUserRating() == null) {
holder.item.ratingIndicatorImageView.setVisibility(View.GONE);
}
holder.item.preferredIcon.setVisibility(song.getStarred() != null ? View.VISIBLE : View.GONE);
holder.item.ratingBarLayout.setVisibility(song.getUserRating() != null ? View.VISIBLE : View.GONE);
if (song.getUserRating() != null) {
holder.item.oneStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 1 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.twoStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 2 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.threeStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 3 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.fourStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 4 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
holder.item.fiveStarIcon.setImageDrawable(AppCompatResources.getDrawable(holder.itemView.getContext(), song.getUserRating() >= 5 ? R.drawable.ic_star : R.drawable.ic_star_outlined));
}
} else {
holder.item.ratingIndicatorImageView.setVisibility(View.GONE);
}
}
@Override

View file

@ -195,21 +195,6 @@ public class MusicUtil {
return context.getString(R.string.label_placeholder);
}
public static String getRatingNumber(Integer ratingNumber) {
if (ratingNumber == null || !Preferences.showItemRating()) return "";
StringBuilder builder = new StringBuilder();
builder.append("");
builder.append(" ");
for (int i = 0; i < ratingNumber; i++) {
builder.append("");
}
return builder.toString();
}
public static String forceReadableString(String string) {
if (string != null) {
return getReadableString(string)

View file

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
android:width="20dp"
android:height="20dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M19,9H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1zM5,15h14c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1H5c-0.55,0 -1,0.45 -1,1s0.45,1 1,1z" />
android:pathData="M228.29,600Q213,600 202.5,589.71Q192,579.42 192,564.21Q192,549 202.34,538.5Q212.69,528 227.98,528L731.71,528Q747,528 757.5,538.29Q768,548.58 768,563.79Q768,579 757.66,589.5Q747.31,600 732.02,600L228.29,600ZM228.29,432Q213,432 202.5,421.71Q192,411.42 192,396.21Q192,381 202.34,370.5Q212.69,360 227.98,360L731.71,360Q747,360 757.5,370.29Q768,380.58 768,395.79Q768,411 757.66,421.5Q747.31,432 732.02,432L228.29,432Z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="960"
android:viewportWidth="960"
android:width="24dp">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M233,840L298,559L80,370L368,345L480,80L592,345L880,370L662,559L727,840L480,691L233,840Z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M354,673L480,597L606,674L573,530L684,434L538,421L480,285L422,420L276,433L387,530L354,673ZM233,840L298,559L80,370L368,345L480,80L592,345L880,370L662,559L727,840L480,691L233,840ZM480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490L480,490Z" />
</vector>

View file

@ -78,11 +78,11 @@
app:layout_constraintStart_toEndOf="@+id/cover_image_separator"
app:layout_constraintTop_toBottomOf="@+id/search_result_song_title_text_view" />
<FrameLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rating_indicator_image_view"
android:layout_width="wrap_content"
android:layout_width="42dp"
android:layout_height="wrap_content"
android:padding="12dp"
android:paddingVertical="8dp"
app:layout_constraintBottom_toBottomOf="@+id/song_cover_image_view"
app:layout_constraintEnd_toStartOf="@+id/search_result_download_indicator_image_view"
app:layout_constraintStart_toEndOf="@+id/search_result_song_title_text_view"
@ -94,11 +94,53 @@
android:layout_height="18dp"
android:background="@drawable/ic_favorite"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/rating_bar"
app:layout_constraintEnd_toEndOf="@+id/rating_bar"
app:layout_constraintStart_toStartOf="@+id/rating_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</FrameLayout>
<LinearLayout
android:id="@+id/rating_bar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/preferred_icon">
<ImageView
android:id="@+id/one_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/two_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/three_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/four_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/five_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/search_result_download_indicator_image_view"

View file

@ -1,11 +1,12 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:foreground="?attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingHorizontal="24dp"
android:paddingHorizontal="16dp"
android:paddingTop="3dp"
android:paddingBottom="3dp">
@ -30,9 +31,11 @@
android:paddingEnd="12dp"
android:singleLine="true"
android:text="@string/label_placeholder"
app:layout_constraintEnd_toStartOf="@+id/queue_song_holder_image"
app:layout_constraintEnd_toStartOf="@+id/rating_indicator_image_view"
app:layout_constraintStart_toEndOf="@+id/queue_song_cover_image_view"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="@id/queue_song_cover_image_view"
app:layout_constraintBottom_toTopOf="@id/queue_song_subtitle_text_view"
app:layout_constraintVertical_chainStyle="packed"/>
<TextView
android:id="@+id/queue_song_subtitle_text_view"
@ -45,19 +48,84 @@
android:singleLine="true"
android:text="@string/label_placeholder"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@+id/queue_song_holder_image"
app:layout_constraintEnd_toEndOf="@+id/queue_song_title_text_view"
app:layout_constraintStart_toEndOf="@+id/queue_song_cover_image_view"
app:layout_constraintTop_toBottomOf="@+id/queue_song_title_text_view" />
app:layout_constraintTop_toBottomOf="@+id/queue_song_title_text_view"
app:layout_constraintBottom_toBottomOf="@+id/queue_song_cover_image_view"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rating_indicator_image_view"
android:layout_width="42dp"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:layout_marginHorizontal="12dp"
app:layout_constraintBottom_toBottomOf="@+id/queue_song_cover_image_view"
app:layout_constraintEnd_toStartOf="@+id/queue_song_holder_image"
app:layout_constraintStart_toEndOf="@+id/queue_song_title_text_view"
app:layout_constraintTop_toTopOf="@+id/queue_song_cover_image_view">
<ImageView
android:id="@+id/preferred_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@drawable/ic_favorite"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/rating_bar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/preferred_icon">
<ImageView
android:id="@+id/one_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/two_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/three_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/four_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
<ImageView
android:id="@+id/five_star_icon"
android:layout_width="8dp"
android:layout_height="8dp"
tools:src="@drawable/ic_star" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/queue_song_holder_image"
android:layout_width="36dp"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:src="@drawable/ic_drag_handle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/queue_song_cover_image_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintStart_toEndOf="@+id/rating_indicator_image_view"
app:layout_constraintTop_toTopOf="@+id/queue_song_cover_image_view" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -313,7 +313,7 @@
<string name="song_list_page_starred">Lieblingslieder</string>
<string name="song_list_page_top">%1$s\'s Top Tracks</string>
<string name="song_list_page_year">Jahr %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">Abbrechen</string>
<string name="starred_sync_dialog_neutral_button">Weiter</string>
<string name="starred_sync_dialog_positive_button">Weiter und Herunterladen</string>

View file

@ -328,7 +328,7 @@
<string name="song_list_page_starred">Titres favoris</string>
<string name="song_list_page_top">Les meilleurs titres de %1$s</string>
<string name="song_list_page_year">Année %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">Annuler</string>
<string name="starred_sync_dialog_neutral_button">Continuer</string>
<string name="starred_sync_dialog_positive_button">Continuer et télécharger</string>

View file

@ -331,7 +331,7 @@
<string name="song_list_page_starred">즐겨찾기한 트랙</string>
<string name="song_list_page_top">%1$s\의 top tracks</string>
<string name="song_list_page_year">년도 %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">취소</string>
<string name="starred_sync_dialog_neutral_button">계속</string>
<string name="starred_sync_dialog_positive_button">계속해서 다운로드</string>

View file

@ -330,7 +330,7 @@
<string name="song_list_page_starred">Músicas favoritas</string>
<string name="song_list_page_top">Músicas preferidas de %1$s</string>
<string name="song_list_page_year">Ano %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">Cancelar</string>
<string name="starred_sync_dialog_neutral_button">Continuar</string>
<string name="starred_sync_dialog_positive_button">Continuar e baixar</string>

View file

@ -327,7 +327,7 @@
<string name="song_list_page_starred">已收藏的曲目</string>
<string name="song_list_page_top">%1$s 的热门曲目</string>
<string name="song_list_page_year">年份 %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">取消</string>
<string name="starred_sync_dialog_neutral_button">继续</string>
<string name="starred_sync_dialog_positive_button">继续并下载</string>

View file

@ -345,7 +345,7 @@
<string name="song_list_page_starred">Starred tracks</string>
<string name="song_list_page_top">%1$s\'s top tracks</string>
<string name="song_list_page_year">Year %1$d</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s %4$s</string>
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
<string name="starred_sync_dialog_negative_button">Cancel</string>
<string name="starred_sync_dialog_neutral_button">Continue</string>
<string name="starred_sync_dialog_positive_button">Continue and download</string>