feat: implemented a second grid layout for album display on the artist page

This commit is contained in:
antonio 2023-09-17 22:33:25 +02:00
parent 72bd71dea2
commit a04a2072f7
3 changed files with 100 additions and 25 deletions

View file

@ -16,17 +16,20 @@ import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaBrowser; import androidx.media3.session.MediaBrowser;
import androidx.media3.session.SessionToken; import androidx.media3.session.SessionToken;
import androidx.navigation.Navigation; import androidx.navigation.Navigation;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.databinding.FragmentArtistPageBinding; import com.cappielloantonio.tempo.databinding.FragmentArtistPageBinding;
import com.cappielloantonio.tempo.glide.CustomGlideRequest; import com.cappielloantonio.tempo.glide.CustomGlideRequest;
import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper; import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper;
import com.cappielloantonio.tempo.helper.recyclerview.GridItemDecoration;
import com.cappielloantonio.tempo.interfaces.ClickCallback; import com.cappielloantonio.tempo.interfaces.ClickCallback;
import com.cappielloantonio.tempo.service.MediaManager; import com.cappielloantonio.tempo.service.MediaManager;
import com.cappielloantonio.tempo.service.MediaService; import com.cappielloantonio.tempo.service.MediaService;
import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.activity.MainActivity;
import com.cappielloantonio.tempo.ui.adapter.AlbumArtistPageOrSimilarAdapter; import com.cappielloantonio.tempo.ui.adapter.AlbumArtistPageOrSimilarAdapter;
import com.cappielloantonio.tempo.ui.adapter.AlbumCatalogueAdapter;
import com.cappielloantonio.tempo.ui.adapter.ArtistSimilarAdapter; import com.cappielloantonio.tempo.ui.adapter.ArtistSimilarAdapter;
import com.cappielloantonio.tempo.ui.adapter.SongHorizontalAdapter; import com.cappielloantonio.tempo.ui.adapter.SongHorizontalAdapter;
import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.Constants;
@ -42,6 +45,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private SongHorizontalAdapter songHorizontalAdapter; private SongHorizontalAdapter songHorizontalAdapter;
private AlbumArtistPageOrSimilarAdapter albumArtistPageOrSimilarAdapter; private AlbumArtistPageOrSimilarAdapter albumArtistPageOrSimilarAdapter;
private AlbumCatalogueAdapter albumCatalogueAdapter;
private ArtistSimilarAdapter artistSimilarAdapter; private ArtistSimilarAdapter artistSimilarAdapter;
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture; private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
@ -59,7 +63,8 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
initArtistInfo(); initArtistInfo();
initPlayButtons(); initPlayButtons();
initTopSongsView(); initTopSongsView();
initAlbumsView(); initHorizontalAlbumsView();
initVerticalAlbumsView();
initSimilarArtistsView(); initSimilarArtistsView();
return view; return view;
@ -93,6 +98,13 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
bundle.putParcelable(Constants.ARTIST_OBJECT, artistPageViewModel.getArtist()); bundle.putParcelable(Constants.ARTIST_OBJECT, artistPageViewModel.getArtist());
activity.navController.navigate(R.id.action_artistPageFragment_to_songListPageFragment, bundle); activity.navController.navigate(R.id.action_artistPageFragment_to_songListPageFragment, bundle);
}); });
bind.artistPageAlbumsSwitchLayoutTextViewClickable.setOnClickListener(view -> {
boolean isHorizontalRecyclerViewVisible = bind.albumsHorizontalRecyclerView.getVisibility() == View.VISIBLE;
bind.albumsHorizontalRecyclerView.setVisibility(isHorizontalRecyclerViewVisible ? View.GONE : View.VISIBLE);
bind.albumsVerticalRecyclerView.setVisibility(isHorizontalRecyclerViewVisible ? View.VISIBLE : View.GONE);
});
} }
private void initAppBar() { private void initAppBar() {
@ -107,8 +119,9 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private void initArtistInfo() { private void initArtistInfo() {
artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artistInfo -> { artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artistInfo -> {
if(artistInfo == null) { if (artistInfo == null) {
if (bind != null) bind.artistPageBioPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null)
bind.artistPageBioPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.artistPageBioSector.setVisibility(View.GONE); if (bind != null) bind.artistPageBioSector.setVisibility(View.GONE);
} else { } else {
String normalizedBio = MusicUtil.forceReadableString(artistInfo.getBiography()); String normalizedBio = MusicUtil.forceReadableString(artistInfo.getBiography());
@ -131,7 +144,8 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
startActivity(intent); startActivity(intent);
}); });
if (bind != null) bind.artistPageBioPlaceholder.placeholder.setVisibility(View.GONE); if (bind != null)
bind.artistPageBioPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null) bind.artistPageBioSector.setVisibility(View.VISIBLE); if (bind != null) bind.artistPageBioSector.setVisibility(View.VISIBLE);
} }
}); });
@ -168,34 +182,63 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
bind.mostStreamedSongRecyclerView.setAdapter(songHorizontalAdapter); bind.mostStreamedSongRecyclerView.setAdapter(songHorizontalAdapter);
artistPageViewModel.getArtistTopSongList().observe(getViewLifecycleOwner(), songs -> { artistPageViewModel.getArtistTopSongList().observe(getViewLifecycleOwner(), songs -> {
if (songs == null) { if (songs == null) {
if (bind != null) bind.artistPageTopTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null)
bind.artistPageTopTracksPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.artistPageTopSongsSector.setVisibility(View.GONE); if (bind != null) bind.artistPageTopSongsSector.setVisibility(View.GONE);
} else { } else {
if (bind != null) bind.artistPageTopTracksPlaceholder.placeholder.setVisibility(View.GONE); if (bind != null)
if (bind != null) bind.artistPageTopSongsSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); bind.artistPageTopTracksPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.artistPageTopSongsSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE);
songHorizontalAdapter.setItems(songs); songHorizontalAdapter.setItems(songs);
} }
}); });
} }
private void initAlbumsView() { private void initHorizontalAlbumsView() {
bind.albumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.albumsHorizontalRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
albumArtistPageOrSimilarAdapter = new AlbumArtistPageOrSimilarAdapter(this); albumArtistPageOrSimilarAdapter = new AlbumArtistPageOrSimilarAdapter(this);
bind.albumsRecyclerView.setAdapter(albumArtistPageOrSimilarAdapter); bind.albumsHorizontalRecyclerView.setAdapter(albumArtistPageOrSimilarAdapter);
artistPageViewModel.getAlbumList().observe(getViewLifecycleOwner(), albums -> { artistPageViewModel.getAlbumList().observe(getViewLifecycleOwner(), albums -> {
if (albums == null) { if (albums == null) {
if (bind != null) bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null)
bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.artistPageAlbumsSector.setVisibility(View.GONE); if (bind != null) bind.artistPageAlbumsSector.setVisibility(View.GONE);
} else { } else {
if (bind != null) bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.GONE); if (bind != null)
if (bind != null) bind.artistPageAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.artistPageAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE);
albumArtistPageOrSimilarAdapter.setItems(albums); albumArtistPageOrSimilarAdapter.setItems(albums);
} }
}); });
CustomLinearSnapHelper albumSnapHelper = new CustomLinearSnapHelper(); CustomLinearSnapHelper albumSnapHelper = new CustomLinearSnapHelper();
albumSnapHelper.attachToRecyclerView(bind.albumsRecyclerView); albumSnapHelper.attachToRecyclerView(bind.albumsHorizontalRecyclerView);
}
private void initVerticalAlbumsView() {
bind.albumsVerticalRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2));
bind.albumsVerticalRecyclerView.addItemDecoration(new GridItemDecoration(2, 20, false));
bind.albumsVerticalRecyclerView.setHasFixedSize(true);
albumCatalogueAdapter = new AlbumCatalogueAdapter(this);
bind.albumsVerticalRecyclerView.setAdapter(albumCatalogueAdapter);
artistPageViewModel.getAlbumList().observe(getViewLifecycleOwner(), albums -> {
if (albums == null) {
if (bind != null)
bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.artistPageAlbumsSector.setVisibility(View.GONE);
} else {
if (bind != null)
bind.artistPageAlbumPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.artistPageAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE);
albumCatalogueAdapter.setItems(albums);
}
});
} }
private void initSimilarArtistsView() { private void initSimilarArtistsView() {
@ -206,11 +249,14 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
bind.similarArtistsRecyclerView.setAdapter(artistSimilarAdapter); bind.similarArtistsRecyclerView.setAdapter(artistSimilarAdapter);
artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artist -> { artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artist -> {
if (artist == null) { if (artist == null) {
if (bind != null) bind.artistPageSimilarArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null)
bind.artistPageSimilarArtistPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.similarArtistSector.setVisibility(View.GONE); if (bind != null) bind.similarArtistSector.setVisibility(View.GONE);
} else { } else {
if (bind != null) bind.artistPageSimilarArtistPlaceholder.placeholder.setVisibility(View.GONE); if (bind != null)
if (bind != null) bind.similarArtistSector.setVisibility(!artist.getSimilarArtists().isEmpty() ? View.VISIBLE : View.GONE); bind.artistPageSimilarArtistPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null)
bind.similarArtistSector.setVisibility(!artist.getSimilarArtists().isEmpty() ? View.VISIBLE : View.GONE);
artistSimilarAdapter.setItems(artist.getSimilarArtists()); artistSimilarAdapter.setItems(artist.getSimilarArtists());
} }
}); });

View file

@ -204,17 +204,31 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<TextView <LinearLayout
style="@style/TitleLarge"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="16dp" android:orientation="horizontal">
android:paddingTop="8dp"
android:paddingEnd="20dp" <TextView
android:text="@string/artist_page_title_album_section" /> style="@style/TitleLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="16dp"
android:paddingEnd="8dp"
android:text="@string/artist_page_title_album_section" />
<TextView
android:id="@+id/artist_page_albums_switch_layout_text_view_clickable"
style="@style/TitleMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="16dp"
android:text="@string/artist_page_switch_layout_button" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/albums_recycler_view" android:id="@+id/albums_horizontal_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@ -223,7 +237,21 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingEnd="8dp" android:paddingEnd="8dp"
android:paddingBottom="8dp" /> android:paddingBottom="8dp"
android:visibility="visible"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/albums_vertical_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:visibility="gone"/>
</LinearLayout> </LinearLayout>
<include <include

View file

@ -39,6 +39,7 @@
<string name="artist_list_page_title">Artists</string> <string name="artist_list_page_title">Artists</string>
<string name="artist_page_radio_button">Radio</string> <string name="artist_page_radio_button">Radio</string>
<string name="artist_page_shuffle_button">Shuffle</string> <string name="artist_page_shuffle_button">Shuffle</string>
<string name="artist_page_switch_layout_button">Switch layout</string>
<string name="artist_page_title_album_more_like_this_button">More like this</string> <string name="artist_page_title_album_more_like_this_button">More like this</string>
<string name="artist_page_title_album_section">Albums</string> <string name="artist_page_title_album_section">Albums</string>
<string name="artist_page_title_biography_more_button">More</string> <string name="artist_page_title_biography_more_button">More</string>