Simplified download list UI

This commit is contained in:
antonio 2023-03-10 11:20:20 +01:00
parent 3e7d260d6a
commit d0e62fcae1
9 changed files with 223 additions and 505 deletions

View file

@ -0,0 +1,116 @@
package com.cappielloantonio.play.adapter;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.media3.common.util.UnstableApi;
import androidx.recyclerview.widget.RecyclerView;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.interfaces.ClickCallback;
import com.cappielloantonio.play.subsonic.models.Child;
import com.cappielloantonio.play.util.MusicUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@UnstableApi
public class DownloadHorizontalAdapter extends RecyclerView.Adapter<DownloadHorizontalAdapter.ViewHolder> {
private final Context context;
private final ClickCallback click;
private List<Child> songs;
public DownloadHorizontalAdapter(Context context, ClickCallback click) {
this.context = context;
this.click = click;
this.songs = Collections.emptyList();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_download, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Child song = songs.get(position);
holder.songTitle.setText(MusicUtil.getReadableString(song.getTitle()));
holder.songArtist.setText(context.getString(R.string.song_subtitle_formatter, MusicUtil.getReadableString(song.getArtist()), MusicUtil.getReadableDurationString(song.getDuration(), false)));
holder.songAlbum.setText(MusicUtil.getReadableString(song.getAlbum()));
if (position > 0 && songs.get(position - 1) != null && !Objects.equals(songs.get(position - 1).getAlbum(), songs.get(position).getAlbum())) {
holder.divider.setPadding(0, 12, 0, 0);
} else {
if (position > 0) holder.divider.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return songs.size();
}
public void setItems(List<Child> songs) {
this.songs = songs;
notifyDataSetChanged();
}
public Child getItem(int id) {
return songs.get(id);
}
public class ViewHolder extends RecyclerView.ViewHolder {
View divider;
TextView songTitle;
TextView songArtist;
TextView songAlbum;
ImageView more;
ViewHolder(View itemView) {
super(itemView);
divider = itemView.findViewById(R.id.divider);
songTitle = itemView.findViewById(R.id.downloaded_song_title_text_view);
songArtist = itemView.findViewById(R.id.downloaded_song_artist_text_view);
songAlbum = itemView.findViewById(R.id.downloaded_song_album_text_view);
more = itemView.findViewById(R.id.downloaded_song_more_button);
songTitle.setSelected(true);
songArtist.setSelected(true);
itemView.setOnClickListener(v -> onClick());
itemView.setOnLongClickListener(v -> onLongClick());
more.setOnClickListener(v -> onLongClick());
}
public void onClick() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("songs_object", new ArrayList<>(songs));
bundle.putInt("position", getBindingAdapterPosition());
click.onMediaClick(bundle);
}
private boolean onLongClick() {
Bundle bundle = new Bundle();
bundle.putParcelable("song_object", songs.get(getBindingAdapterPosition()));
click.onMediaLongClick(bundle);
return false;
}
}
}

View file

@ -12,33 +12,9 @@ import java.util.List;
@Dao
public interface DownloadDao {
@Query("SELECT * FROM download")
@Query("SELECT * FROM download ORDER BY album, track ASC")
LiveData<List<Download>> getAll();
@Query("SELECT * FROM download WHERE playlist_id IS NULL GROUP BY artist LIMIT :size")
LiveData<List<Download>> getSampleArtist(int size);
@Query("SELECT * FROM download WHERE playlist_id IS NULL GROUP BY album LIMIT :size")
LiveData<List<Download>> getSampleAlbum(int size);
@Query("SELECT * FROM download WHERE playlist_id IS NOT NULL GROUP BY playlist_id LIMIT :size")
LiveData<List<Download>> getSamplePlaylist(int size);
@Query("SELECT * FROM download LIMIT :size")
LiveData<List<Download>> getSample(int size);
@Query("SELECT * FROM download WHERE artist=:artistId")
LiveData<List<Download>> getAllFromArtist(String artistId);
@Query("SELECT * FROM download WHERE album=:albumId ORDER BY track ASC")
LiveData<List<Download>> getAllFromAlbum(String albumId);
@Query("SELECT * FROM download WHERE playlist_id=:playlistId")
LiveData<List<Download>> getAllFromPlaylist(String playlistId);
@Query("SELECT * FROM download WHERE playlist_id IS NOT NULL GROUP BY playlist_id")
LiveData<List<Download>> getAllPlaylists();
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Download download);

View file

@ -7,7 +7,6 @@ import androidx.lifecycle.LiveData;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.DownloadDao;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.util.Preferences;
import java.util.List;
@ -23,30 +22,6 @@ public class DownloadRepository {
return downloadDao.getAll();
}
public LiveData<List<Download>> getLiveDownloadSample(int size, boolean isArtist, boolean isAlbum, boolean isTrack, boolean isPlaylist) {
if (isArtist) return downloadDao.getSampleArtist(size);
else if (isAlbum) return downloadDao.getSampleAlbum(size);
else if (isTrack) return downloadDao.getSample(size);
else if (isPlaylist) return downloadDao.getSamplePlaylist(size);
else return downloadDao.getSample(size);
}
public LiveData<List<Download>> getLiveDownloadFromArtist(String artistId) {
return downloadDao.getAllFromArtist(artistId);
}
public LiveData<List<Download>> getLiveDownloadFromAlbum(String albumId) {
return downloadDao.getAllFromAlbum(albumId);
}
public LiveData<List<Download>> getLiveDownloadFromPlaylist(String playlistId) {
return downloadDao.getAllFromPlaylist(playlistId);
}
public LiveData<List<Download>> getLivePlaylist() {
return downloadDao.getAllPlaylists();
}
public void insert(Download download) {
InsertThreadSafe insert = new InsertThreadSafe(downloadDao, download);
Thread thread = new Thread(insert);

View file

@ -17,27 +17,15 @@ import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaBrowser;
import androidx.media3.session.SessionToken;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.SnapHelper;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.adapter.AlbumHorizontalAdapter;
import com.cappielloantonio.play.adapter.ArtistHorizontalAdapter;
import com.cappielloantonio.play.adapter.PlaylistHorizontalAdapter;
import com.cappielloantonio.play.adapter.SongHorizontalAdapter;
import com.cappielloantonio.play.adapter.DownloadHorizontalAdapter;
import com.cappielloantonio.play.databinding.FragmentDownloadBinding;
import com.cappielloantonio.play.helper.recyclerview.DotsIndicatorDecoration;
import com.cappielloantonio.play.interfaces.ClickCallback;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Media;
import com.cappielloantonio.play.model.Playlist;
import com.cappielloantonio.play.service.MediaManager;
import com.cappielloantonio.play.service.MediaService;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.UIUtil;
import com.cappielloantonio.play.viewmodel.DownloadViewModel;
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.common.util.concurrent.ListenableFuture;
@ -50,10 +38,7 @@ public class DownloadFragment extends Fragment implements ClickCallback {
private MainActivity activity;
private DownloadViewModel downloadViewModel;
private ArtistHorizontalAdapter downloadedArtistAdapter;
private AlbumHorizontalAdapter downloadedAlbumAdapter;
private SongHorizontalAdapter downloadedTrackAdapter;
private PlaylistHorizontalAdapter playlistHorizontalAdapter;
private DownloadHorizontalAdapter downloadHorizontalAdapter;
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
@ -79,8 +64,6 @@ public class DownloadFragment extends Fragment implements ClickCallback {
View view = bind.getRoot();
downloadViewModel = new ViewModelProvider(requireActivity()).get(DownloadViewModel.class);
init();
return view;
}
@ -89,11 +72,7 @@ public class DownloadFragment extends Fragment implements ClickCallback {
super.onViewCreated(view, savedInstanceState);
initAppBar();
initDownloadedArtistView();
initDownloadedAlbumView();
initDownloadedSongView();
initDownloadedPlaylistSlideView();
initPlaceholder();
}
@Override
@ -130,173 +109,36 @@ public class DownloadFragment extends Fragment implements ClickCallback {
return false;
}
private void init() {
bind.downloadedArtistTextViewClickable.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putString(Artist.DOWNLOADED, Artist.DOWNLOADED);
activity.navController.navigate(R.id.action_downloadFragment_to_artistListPageFragment, bundle);
});
bind.downloadedAlbumTextViewClickable.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putString(Album.DOWNLOADED, Album.DOWNLOADED);
activity.navController.navigate(R.id.action_downloadFragment_to_albumListPageFragment, bundle);
});
bind.downloadedTracksTextViewClickable.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putString(Media.DOWNLOADED, Media.DOWNLOADED);
activity.navController.navigate(R.id.action_downloadFragment_to_songListPageFragment, bundle);
});
bind.downloadedPlaylistTextViewClickable.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putString(Playlist.DOWNLOADED, Playlist.DOWNLOADED);
activity.navController.navigate(R.id.action_downloadFragment_to_playlistCatalogueFragment, bundle);
});
}
private void initAppBar() {
activity.setSupportActionBar(bind.toolbar);
Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null));
}
private void initDownloadedArtistView() {
bind.downloadedArtistRecyclerView.setHasFixedSize(true);
downloadedArtistAdapter = new ArtistHorizontalAdapter(requireContext(), this);
bind.downloadedArtistRecyclerView.setAdapter(downloadedArtistAdapter);
downloadViewModel.getDownloadedArtists(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), artists -> {
if (artists == null) {
if (bind != null)
bind.downloadDownloadedArtistPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.downloadDownloadedArtistSector.setVisibility(View.GONE);
} else {
if (bind != null)
bind.downloadDownloadedArtistPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.downloadDownloadedArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE);
if (bind != null)
bind.downloadedArtistRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(artists.size(), 5), GridLayoutManager.HORIZONTAL, false));
downloadedArtistAdapter.setItems(artists);
}
});
SnapHelper starredArtistSnapHelper = new PagerSnapHelper();
starredArtistSnapHelper.attachToRecyclerView(bind.downloadedArtistRecyclerView);
bind.downloadedArtistRecyclerView.addItemDecoration(
new DotsIndicatorDecoration(
getResources().getDimensionPixelSize(R.dimen.radius),
getResources().getDimensionPixelSize(R.dimen.radius) * 4,
getResources().getDimensionPixelSize(R.dimen.dots_height),
requireContext().getResources().getColor(R.color.titleTextColor, null),
requireContext().getResources().getColor(R.color.titleTextColor, null))
);
}
private void initDownloadedAlbumView() {
bind.downloadedAlbumRecyclerView.setHasFixedSize(true);
downloadedAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), this, true);
bind.downloadedAlbumRecyclerView.setAdapter(downloadedAlbumAdapter);
downloadViewModel.getDownloadedAlbums(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), albums -> {
if (albums == null) {
if (bind != null)
bind.downloadDownloadedAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.downloadDownloadedAlbumSector.setVisibility(View.GONE);
} else {
if (bind != null)
bind.downloadDownloadedAlbumPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.downloadDownloadedAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE);
if (bind != null)
bind.downloadedAlbumRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false));
downloadedAlbumAdapter.setItems(albums);
}
});
SnapHelper starredAlbumSnapHelper = new PagerSnapHelper();
starredAlbumSnapHelper.attachToRecyclerView(bind.downloadedAlbumRecyclerView);
bind.downloadedAlbumRecyclerView.addItemDecoration(
new DotsIndicatorDecoration(
getResources().getDimensionPixelSize(R.dimen.radius),
getResources().getDimensionPixelSize(R.dimen.radius) * 4,
getResources().getDimensionPixelSize(R.dimen.dots_height),
requireContext().getResources().getColor(R.color.titleTextColor, null),
requireContext().getResources().getColor(R.color.titleTextColor, null))
);
}
private void initDownloadedSongView() {
bind.downloadedTracksRecyclerView.setHasFixedSize(true);
downloadedTrackAdapter = new SongHorizontalAdapter(requireContext(), this, true);
bind.downloadedTracksRecyclerView.setAdapter(downloadedTrackAdapter);
downloadViewModel.getDownloadedTracks(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), songs -> {
if (songs == null) {
if (bind != null)
downloadHorizontalAdapter = new DownloadHorizontalAdapter(requireContext(), this);
bind.downloadedTracksRecyclerView.setAdapter(downloadHorizontalAdapter);
downloadViewModel.getDownloadedTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
if (songs == null || songs.isEmpty()) {
if (bind != null) {
bind.emptyDownloadLayout.setVisibility(View.VISIBLE);
bind.fragmentDownloadNestedScrollView.setVisibility(View.GONE);
bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.downloadDownloadedTracksSector.setVisibility(View.GONE);
bind.downloadDownloadedTracksSector.setVisibility(View.GONE);
}
} else {
if (bind != null)
if (bind != null) {
bind.emptyDownloadLayout.setVisibility(View.GONE);
bind.fragmentDownloadNestedScrollView.setVisibility(View.VISIBLE);
bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.downloadDownloadedTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE);
if (bind != null)
bind.downloadedTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(songs.size(), 5), GridLayoutManager.HORIZONTAL, false));
bind.downloadDownloadedTracksSector.setVisibility(View.VISIBLE);
bind.downloadedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
downloadedTrackAdapter.setItems(songs);
}
});
SnapHelper starredTrackSnapHelper = new PagerSnapHelper();
starredTrackSnapHelper.attachToRecyclerView(bind.downloadedTracksRecyclerView);
bind.downloadedTracksRecyclerView.addItemDecoration(
new DotsIndicatorDecoration(
getResources().getDimensionPixelSize(R.dimen.radius),
getResources().getDimensionPixelSize(R.dimen.radius) * 4,
getResources().getDimensionPixelSize(R.dimen.dots_height),
requireContext().getResources().getColor(R.color.titleTextColor, null),
requireContext().getResources().getColor(R.color.titleTextColor, null))
);
}
private void initDownloadedPlaylistSlideView() {
bind.downloadedPlaylistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.downloadedPlaylistRecyclerView.setHasFixedSize(true);
playlistHorizontalAdapter = new PlaylistHorizontalAdapter(requireContext(), this);
bind.downloadedPlaylistRecyclerView.setAdapter(playlistHorizontalAdapter);
downloadViewModel.getDownloadedPlaylists(getViewLifecycleOwner(), 5).observe(getViewLifecycleOwner(), playlists -> {
if (playlists == null) {
if (bind != null)
bind.downloadDownloadedPlaylistPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.downloadDownloadedPlaylistSector.setVisibility(View.GONE);
} else {
if (bind != null)
bind.downloadDownloadedPlaylistPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.downloadDownloadedPlaylistSector.setVisibility(!playlists.isEmpty() ? View.VISIBLE : View.GONE);
// TODO
// playlistHorizontalAdapter.setItems(playlists);
}
});
}
private void initPlaceholder() {
downloadViewModel.getDownloadedTracks(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), songs -> {
if ((songs != null && !songs.isEmpty())) {
if (bind != null) bind.emptyDownloadLayout.setVisibility(View.GONE);
if (bind != null) bind.fragmentDownloadNestedScrollView.setVisibility(View.VISIBLE);
} else {
if (bind != null) bind.emptyDownloadLayout.setVisibility(View.VISIBLE);
if (bind != null) bind.fragmentDownloadNestedScrollView.setVisibility(View.GONE);
downloadHorizontalAdapter.setItems(songs);
}
}
});
}
@ -319,30 +161,4 @@ public class DownloadFragment extends Fragment implements ClickCallback {
public void onMediaLongClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle);
}
@Override
public void onAlbumClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle);
}
@Override
public void onAlbumLongClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle);
}
@Override
public void onArtistClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.albumListPageFragment, bundle);
}
@Override
public void onArtistLongClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle);
}
@Override
public void onPlaylistClick(Bundle bundle) {
bundle.putBoolean("is_offline", true);
Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle);
}
}

View file

@ -34,50 +34,8 @@ public class DownloadViewModel extends AndroidViewModel {
downloadRepository = new DownloadRepository(application);
}
public LiveData<List<ArtistID3>> getDownloadedArtists(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, true, false, false, false)
.observe(owner, downloads -> downloadedArtistSample.postValue(downloads.stream().map(download -> {
ArtistID3 artist = new ArtistID3();
artist.setId(download.getArtistId());
artist.setName(download.getArtist());
artist.setCoverArtId(download.getCoverArtId());
// artist.setAlbumCount(0);
// artist.setStarred(null);
return artist;
}).collect(Collectors.toList())));
return downloadedArtistSample;
}
public LiveData<List<AlbumID3>> getDownloadedAlbums(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, false, true, false, false)
.observe(owner, downloads -> downloadedAlbumSample.postValue(downloads.stream().map(download -> {
AlbumID3 album = new AlbumID3();
album.setId(download.getAlbumId());
album.setName(download.getAlbum());
album.setArtist(album.getArtist());
album.setArtistId(album.getArtistId());
album.setCoverArtId(album.getCoverArtId());
// album.setSongCount(0);
// album.setDuration(0);
// album.setPlayCount(null);
// album.setCreated(null);
// album.setStarred(null);
album.setYear(album.getYear());
// album.setGenre(null);
return album;
}).collect(Collectors.toList())));
return downloadedAlbumSample;
}
public LiveData<List<Child>> getDownloadedTracks(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, false, false, true, false).observe(owner, downloads -> downloadedTrackSample.postValue(downloads.stream().map(download -> (Child) download).collect(Collectors.toList())));
public LiveData<List<Child>> getDownloadedTracks(LifecycleOwner owner) {
downloadRepository.getLiveDownload().observe(owner, downloads -> downloadedTrackSample.postValue(downloads.stream().map(download -> (Child) download).collect(Collectors.toList())));
return downloadedTrackSample;
}
public LiveData<List<Playlist>> getDownloadedPlaylists(LifecycleOwner owner, int size) {
downloadRepository.getLiveDownloadSample(size, false, false, false, true).observe(owner, downloads -> downloadedPlaylistSample.postValue(MappingUtil.mapDownloadToPlaylist(downloads)));
return downloadedPlaylistSample;
}
}

View file

@ -67,12 +67,6 @@ public class SongListPageViewModel extends AndroidViewModel {
case Media.STARRED:
songList = songRepository.getStarredSongs(false, -1);
break;
case Media.DOWNLOADED:
downloadRepository.getLiveDownload().observe(owner, downloads -> songList.setValue(downloads.stream().map(download -> (Child) download).collect(Collectors.toList())));
break;
case Media.FROM_ALBUM:
downloadRepository.getLiveDownloadFromAlbum(album.getId()).observe(owner, downloads -> songList.setValue(downloads.stream().map(download -> (Child) download).collect(Collectors.toList())));
break;
}
return songList;

View file

@ -79,7 +79,6 @@
android:id="@+id/fragment_download_nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
@ -89,118 +88,6 @@
android:orientation="vertical"
android:paddingBottom="@dimen/global_padding_bottom">
<!-- Downloaded artist -->
<LinearLayout
android:id="@+id/download_downloaded_artist_sector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<!-- Label and button -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingEnd="8dp">
<TextView
android:id="@+id/downloaded_artist_text_view_refreshable"
style="@style/TitleLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:text="@string/download_title_artist_section" />
<TextView
android:id="@+id/downloaded_artist_text_view_clickable"
style="@style/TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:text="@string/download_title_artist_see_all_button" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloaded_artist_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
<include
android:id="@+id/download_downloaded_artist_placeholder"
layout="@layout/item_placeholder_album"
android:visibility="gone" />
<!-- Downloaded albums -->
<LinearLayout
android:id="@+id/download_downloaded_album_sector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Label and button -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="8dp">
<TextView
android:id="@+id/downloaded_album_text_view_refreshable"
style="@style/TitleLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_album_section" />
<TextView
android:id="@+id/downloaded_album_text_view_clickable"
style="@style/TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_album_see_all" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloaded_album_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
<include
android:id="@+id/download_downloaded_album_placeholder"
layout="@layout/item_placeholder_album"
android:visibility="gone" />
<!-- Downloaded tracks -->
<LinearLayout
android:id="@+id/download_downloaded_tracks_sector"
@ -208,47 +95,22 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Label and button -->
<LinearLayout
<TextView
android:id="@+id/downloaded_tracks_text_view_refreshable"
style="@style/TitleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="8dp"
android:layout_marginBottom="8dp"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp">
<TextView
android:id="@+id/downloaded_tracks_text_view_refreshable"
style="@style/TitleLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_tracks_section" />
<TextView
android:id="@+id/downloaded_tracks_text_view_clickable"
style="@style/TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_tracks_see_all_button" />
</LinearLayout>
android:paddingEnd="16dp"
android:text="@string/download_title_tracks_section" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloaded_tracks_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
@ -256,62 +118,6 @@
android:id="@+id/download_downloaded_tracks_placeholder"
layout="@layout/item_placeholder_horizontal"
android:visibility="gone" />
<LinearLayout
android:id="@+id/download_downloaded_playlist_sector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<!-- Label and button -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="8dp">
<TextView
android:id="@+id/downloaded_playlist_text_view_refreshable"
style="@style/TitleLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_playlist_section" />
<TextView
android:id="@+id/downloaded_playlist_text_view_clickable"
style="@style/TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:text="@string/download_title_playlist_see_all_button" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/downloaded_playlist_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
</LinearLayout>
<include
android:id="@+id/download_downloaded_playlist_placeholder"
layout="@layout/item_placeholder_horizontal"
android:visibility="gone" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,71 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clipChildren="false"
android:orientation="horizontal"
android:paddingStart="16dp">
<LinearLayout
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/downloaded_song_album_text_view"
style="@style/LabelExtraSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp" />
<View
style="@style/Divider"
android:layout_gravity="center_vertical" />
</LinearLayout>
<TextView
android:id="@+id/downloaded_song_title_text_view"
style="@style/LabelMedium"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingTop="6dp"
android:paddingEnd="12dp"
android:singleLine="true"
android:text="@string/label_placeholder"
app:layout_constraintEnd_toStartOf="@+id/downloaded_song_more_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider" />
<TextView
android:id="@+id/downloaded_song_artist_text_view"
style="@style/LabelSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingEnd="12dp"
android:paddingBottom="6dp"
android:singleLine="true"
android:text="@string/label_placeholder"
app:layout_constraintEnd_toStartOf="@+id/downloaded_song_more_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/downloaded_song_title_text_view" />
<ImageView
android:id="@+id/downloaded_song_more_button"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="10dp"
android:background="@drawable/ic_more_vert"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -67,6 +67,12 @@
<item name="android:textColor">@color/subtitleTextColor</item>
</style>
<style name="LabelExtraSmall" parent="InterFontFamily">
<item name="android:textSize">10sp</item>
<item name="android:textFontWeight">300</item>
<item name="android:textColor">@color/subtitleTextColor</item>
</style>
<style name="BodyLarge" parent="InterFontFamily">
<item name="android:textSize">24sp</item>