feat: updated podcast channel UI

This commit is contained in:
antonio 2023-07-30 12:23:49 +02:00
parent 7a8880ee68
commit f9573b3eab
2 changed files with 124 additions and 126 deletions

View file

@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupMenu;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
@ -17,7 +18,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.databinding.FragmentPodcastChannelPageBinding;
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
import com.cappielloantonio.tempo.interfaces.ClickCallback;
import com.cappielloantonio.tempo.service.MediaManager;
import com.cappielloantonio.tempo.service.MediaService;
@ -31,8 +31,6 @@ import com.cappielloantonio.tempo.viewmodel.PodcastChannelPageViewModel;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@UnstableApi
public class PodcastChannelPageFragment extends Fragment implements ClickCallback {
@ -84,28 +82,26 @@ public class PodcastChannelPageFragment extends Fragment implements ClickCallbac
}
private void initAppBar() {
activity.setSupportActionBar(bind.animToolbar);
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
activity.setSupportActionBar(bind.toolbar);
bind.collapsingToolbar.setTitle(MusicUtil.getReadableString(podcastChannelPageViewModel.getPodcastChannel().getTitle()));
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
bind.collapsingToolbar.setExpandedTitleColor(getResources().getColor(R.color.white, null));
if (activity.getSupportActionBar() != null) {
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
activity.getSupportActionBar().setDisplayShowHomeEnabled(true);
}
bind.toolbar.setTitle(MusicUtil.getReadableString(podcastChannelPageViewModel.getPodcastChannel().getTitle()));
bind.toolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
bind.toolbar.setTitle(MusicUtil.getReadableString(podcastChannelPageViewModel.getPodcastChannel().getTitle()));
}
private void initPodcastChannelInfo() {
String normalizePodcastChannelDescription = MusicUtil.forceReadableString(podcastChannelPageViewModel.getPodcastChannel().getDescription());
if (bind != null)
if (bind != null) {
bind.podcastChannelDescriptionTextView.setVisibility(!normalizePodcastChannelDescription.trim().isEmpty() ? View.VISIBLE : View.GONE);
if (getContext() != null && bind != null) CustomGlideRequest.Builder
.from(requireContext(), podcastChannelPageViewModel.getPodcastChannel().getCoverArtId())
.build()
.into(bind.podcastChannelBackdropImageView);
if (bind != null)
bind.podcastChannelDescriptionTextView.setText(normalizePodcastChannelDescription);
bind.podcastEpisodesFilterImageView.setOnClickListener(view -> showPopupMenu(view, R.menu.filter_podcast_episode_popup_menu));
}
}
private void initPodcastChannelEpisodesView() {
@ -116,22 +112,25 @@ public class PodcastChannelPageFragment extends Fragment implements ClickCallbac
bind.podcastEpisodesRecyclerView.setAdapter(podcastEpisodeAdapter);
podcastChannelPageViewModel.getPodcastChannelEpisodes().observe(getViewLifecycleOwner(), channels -> {
if (channels == null) {
if (bind != null)
bind.podcastChannelPageEpisodesPlaceholder.placeholder.setVisibility(View.VISIBLE);
if (bind != null) bind.podcastChannelPageEpisodesSector.setVisibility(View.GONE);
if (bind != null) {
bind.podcastEpisodesRecyclerView.setVisibility(View.GONE);
bind.podcastEpisodesAvailabilityTextView.setVisibility(View.VISIBLE);
}
} else {
if (bind != null)
bind.podcastChannelPageEpisodesPlaceholder.placeholder.setVisibility(View.GONE);
if (bind != null) {
bind.podcastEpisodesRecyclerView.setVisibility(View.VISIBLE);
bind.podcastEpisodesAvailabilityTextView.setVisibility(View.GONE);
}
if (!channels.isEmpty() && channels.get(0) != null && channels.get(0).getEpisodes() != null) {
List<PodcastEpisode> availableEpisode = channels.get(0).getEpisodes().stream().filter(podcastEpisode -> Objects.equals(podcastEpisode.getStatus(), "completed")).collect(Collectors.toList());
List<PodcastEpisode> availableEpisode = channels.get(0).getEpisodes();
if (bind != null) {
if (bind != null && availableEpisode != null) {
bind.podcastEpisodesRecyclerView.setVisibility(availableEpisode.isEmpty() ? View.GONE : View.VISIBLE);
bind.podcastEpisodesAvailabilityTextView.setVisibility(availableEpisode.isEmpty() ? View.VISIBLE : View.GONE);
}
podcastEpisodeAdapter.setItems(availableEpisode);
podcastEpisodeAdapter.setItems(availableEpisode);
}
}
}
});
@ -145,6 +144,25 @@ public class PodcastChannelPageFragment extends Fragment implements ClickCallbac
MediaBrowser.releaseFuture(mediaBrowserListenableFuture);
}
private void showPopupMenu(View view, int menuResource) {
PopupMenu popup = new PopupMenu(requireContext(), view);
popup.getMenuInflater().inflate(menuResource, popup.getMenu());
popup.setOnMenuItemClickListener(menuItem -> {
if (menuItem.getItemId() == R.id.menu_podcast_filter_download) {
podcastEpisodeAdapter.sort(Constants.PODCAST_FILTER_BY_DOWNLOAD);
return true;
} else if (menuItem.getItemId() == R.id.menu_podcast_filter_all) {
podcastEpisodeAdapter.sort(Constants.PODCAST_FILTER_BY_ALL);
return true;
}
return false;
});
popup.show();
}
@Override
public void onPodcastEpisodeClick(Bundle bundle) {
MediaManager.startPodcast(mediaBrowserListenableFuture, bundle.getParcelable(Constants.PODCAST_OBJECT));

View file

@ -1,74 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/appbar_header_height">
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_arrow_back" />
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorSurface"
app:expandedTitleMarginStart="@dimen/activity_margin_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/podcast_channel_backdrop_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/appbar_header_height"
android:layout_gravity="top"
android:background="@drawable/gradient_backdrop_background_image" />
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/fragment_artist_page_nested_scroll_view"
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:layout_height="match_parent">
<LinearLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingTop="18dp"
android:paddingBottom="@dimen/global_padding_bottom">
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/podcast_channel_page_bio_sector"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/podcast_channel_page_info_sector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="22dp">
android:background="?attr/colorSurface"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<TextView
android:id="@+id/podcast_channel_description_label"
style="@style/TitleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="8dp"
android:text="@string/podcast_channel_page_title_description_section" />
android:text="@string/podcast_channel_page_title_description_section"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/podcast_channel_description_text_view"
@ -77,63 +48,72 @@
android:layout_height="match_parent"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp" />
</LinearLayout>
android:paddingEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/podcast_channel_description_label" />
<include
android:id="@+id/podcast_channel_page_description_placeholder"
layout="@layout/item_placehoder_biography"
android:visibility="gone" />
<View
android:id="@+id/upper_button_divider"
style="@style/Divider"
android:layout_marginHorizontal="16dp" />
<!-- Label and button -->
<LinearLayout
android:id="@+id/podcast_channel_page_episodes_sector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="22dp">
<View
android:id="@+id/upper_button_divider"
style="@style/Divider"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/podcast_channel_description_text_view" />
<TextView
android:id="@+id/podcast_episodes_section_label"
style="@style/TitleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="8dp"
android:text="@string/podcast_channel_page_title_episode_section" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/podcast_episodes_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:paddingTop="8dp" />
<TextView
android:id="@+id/podcast_episodes_availability_text_view"
style="@style/TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingStart="16dp"
android:paddingEnd="8dp"
android:text="@string/podcast_channel_page_title_no_episode_available"
android:visibility="gone" />
</LinearLayout>
android:paddingBottom="12dp"
android:text="@string/podcast_channel_page_title_episode_section"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/upper_button_divider" />
<include
android:id="@+id/podcast_channel_page_episodes_placeholder"
layout="@layout/item_placeholder_horizontal"
android:visibility="gone" />
<Button
android:id="@+id/podcast_episodes_filter_image_view"
style="@style/Widget.Material3.Button.TonalButton.Icon"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:cornerRadius="30dp"
app:icon="@drawable/ic_filter_list"
app:layout_constraintBottom_toBottomOf="@+id/podcast_episodes_section_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/podcast_episodes_section_label" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/podcast_episodes_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="@dimen/global_padding_bottom"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<TextView
android:id="@+id/podcast_episodes_availability_text_view"
style="@style/TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:text="@string/podcast_channel_page_title_no_episode_available"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>