summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/fragment
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/fragment')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java216
1 files changed, 68 insertions, 148 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
index 5b030f0c2..94a697893 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -6,116 +6,81 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.ClipData;
import android.content.ClipboardManager;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.Space;
-import android.widget.TextView;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.BlendModeColorFilterCompat;
import androidx.core.graphics.BlendModeCompat;
import androidx.fragment.app.Fragment;
-
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.snackbar.Snackbar;
-
-import org.apache.commons.lang3.StringUtils;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.util.ChapterUtils;
import de.danoeh.antennapod.core.util.DateFormatter;
-import de.danoeh.antennapod.model.feed.EmbeddedChapterImage;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.databinding.CoverFragmentBinding;
+import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.model.feed.Chapter;
+import de.danoeh.antennapod.model.feed.EmbeddedChapterImage;
+import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import org.apache.commons.lang3.StringUtils;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import static android.widget.LinearLayout.LayoutParams.MATCH_PARENT;
+import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
/**
* Displays the cover and the title of a FeedItem.
*/
public class CoverFragment extends Fragment {
-
private static final String TAG = "CoverFragment";
- static final double SIXTEEN_BY_NINE = 1.7;
-
- private View root;
- private TextView txtvPodcastTitle;
- private TextView txtvEpisodeTitle;
- private ImageView imgvCover;
- private LinearLayout openDescription;
- private Space counterweight;
- private Space spacer;
- private ImageButton butPrevChapter;
- private ImageButton butNextChapter;
- private LinearLayout episodeDetails;
- private LinearLayout chapterControl;
+ private CoverFragmentBinding viewBinding;
private PlaybackController controller;
private Disposable disposable;
private int displayedChapterIndex = -1;
private Playable media;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- setRetainInstance(true);
- root = inflater.inflate(R.layout.cover_fragment, container, false);
- txtvPodcastTitle = root.findViewById(R.id.txtvPodcastTitle);
- txtvEpisodeTitle = root.findViewById(R.id.txtvEpisodeTitle);
- imgvCover = root.findViewById(R.id.imgvCover);
- episodeDetails = root.findViewById(R.id.episode_details);
- final ImageView descriptionIcon = root.findViewById(R.id.description_icon);
- chapterControl = root.findViewById(R.id.chapterButton);
- butPrevChapter = root.findViewById(R.id.butPrevChapter);
- butNextChapter = root.findViewById(R.id.butNextChapter);
-
- imgvCover.setOnClickListener(v -> onPlayPause());
- openDescription = root.findViewById(R.id.openDescription);
- counterweight = root.findViewById(R.id.counterweight);
- spacer = root.findViewById(R.id.details_spacer);
- View.OnClickListener scrollToDesc = view ->
- ((AudioPlayerFragment) requireParentFragment()).scrollToPage(AudioPlayerFragment.POS_DESCRIPTION, true);
- openDescription.setOnClickListener(scrollToDesc);
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ viewBinding = CoverFragmentBinding.inflate(inflater);
+ viewBinding.imgvCover.setOnClickListener(v -> onPlayPause());
+ viewBinding.openDescription.setOnClickListener(view -> ((AudioPlayerFragment) requireParentFragment())
+ .scrollToPage(AudioPlayerFragment.POS_DESCRIPTION, true));
ColorFilter colorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(
- txtvPodcastTitle.getCurrentTextColor(), BlendModeCompat.SRC_IN);
- butNextChapter.setColorFilter(colorFilter);
- butPrevChapter.setColorFilter(colorFilter);
- descriptionIcon.setColorFilter(colorFilter);
- chapterControl.setOnClickListener(v ->
+ viewBinding.txtvPodcastTitle.getCurrentTextColor(), BlendModeCompat.SRC_IN);
+ viewBinding.butNextChapter.setColorFilter(colorFilter);
+ viewBinding.butPrevChapter.setColorFilter(colorFilter);
+ viewBinding.descriptionIcon.setColorFilter(colorFilter);
+ viewBinding.chapterButton.setOnClickListener(v ->
new ChaptersFragment().show(getChildFragmentManager(), ChaptersFragment.TAG));
- butPrevChapter.setOnClickListener(v -> seekToPrevChapter());
- butNextChapter.setOnClickListener(v -> seekToNextChapter());
-
- return root;
+ viewBinding.butPrevChapter.setOnClickListener(v -> seekToPrevChapter());
+ viewBinding.butNextChapter.setOnClickListener(v -> seekToNextChapter());
+ return viewBinding.getRoot();
}
@Override
@@ -150,7 +115,7 @@ public class CoverFragment extends Fragment {
private void displayMediaInfo(@NonNull Playable media) {
String pubDateStr = DateFormatter.formatAbbrev(getActivity(), media.getPubDate());
- txtvPodcastTitle.setText(StringUtils.stripToEmpty(media.getFeedTitle())
+ viewBinding.txtvPodcastTitle.setText(StringUtils.stripToEmpty(media.getFeedTitle())
+ "\u00A0"
+ "・"
+ "\u00A0"
@@ -158,33 +123,35 @@ public class CoverFragment extends Fragment {
if (media instanceof FeedMedia) {
Intent openFeed = MainActivity.getIntentToOpenFeed(requireContext(),
((FeedMedia) media).getItem().getFeedId());
- txtvPodcastTitle.setOnClickListener(v -> startActivity(openFeed));
+ viewBinding.txtvPodcastTitle.setOnClickListener(v -> startActivity(openFeed));
} else {
- txtvPodcastTitle.setOnClickListener(null);
+ viewBinding.txtvPodcastTitle.setOnClickListener(null);
}
- txtvPodcastTitle.setOnLongClickListener(v -> copyText(media.getFeedTitle()));
- txtvEpisodeTitle.setText(media.getEpisodeTitle());
- txtvEpisodeTitle.setOnLongClickListener(v -> copyText(media.getEpisodeTitle()));
- txtvEpisodeTitle.setOnClickListener(v -> {
- int lines = txtvEpisodeTitle.getLineCount();
+ viewBinding.txtvPodcastTitle.setOnLongClickListener(v -> copyText(media.getFeedTitle()));
+ viewBinding.txtvEpisodeTitle.setText(media.getEpisodeTitle());
+ viewBinding.txtvEpisodeTitle.setOnLongClickListener(v -> copyText(media.getEpisodeTitle()));
+ viewBinding.txtvEpisodeTitle.setOnClickListener(v -> {
+ int lines = viewBinding.txtvEpisodeTitle.getLineCount();
int animUnit = 1500;
- if (lines > txtvEpisodeTitle.getMaxLines()) {
+ if (lines > viewBinding.txtvEpisodeTitle.getMaxLines()) {
+ int titleHeight = viewBinding.txtvEpisodeTitle.getHeight()
+ - viewBinding.txtvEpisodeTitle.getPaddingTop()
+ - viewBinding.txtvEpisodeTitle.getPaddingBottom();
ObjectAnimator verticalMarquee = ObjectAnimator.ofInt(
- txtvEpisodeTitle, "scrollY", 0, (lines - txtvEpisodeTitle.getMaxLines()) * (
- (txtvEpisodeTitle.getHeight() - txtvEpisodeTitle.getPaddingTop()
- - txtvEpisodeTitle.getPaddingBottom()) / txtvEpisodeTitle.getMaxLines()))
+ viewBinding.txtvEpisodeTitle, "scrollY", 0, (lines - viewBinding.txtvEpisodeTitle.getMaxLines())
+ * (titleHeight / viewBinding.txtvEpisodeTitle.getMaxLines()))
.setDuration(lines * animUnit);
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(
- txtvEpisodeTitle, "alpha", 0);
+ viewBinding.txtvEpisodeTitle, "alpha", 0);
fadeOut.setStartDelay(animUnit);
fadeOut.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- txtvEpisodeTitle.scrollTo(0, 0);
+ viewBinding.txtvEpisodeTitle.scrollTo(0, 0);
}
});
ObjectAnimator fadeBackIn = ObjectAnimator.ofFloat(
- txtvEpisodeTitle, "alpha", 1);
+ viewBinding.txtvEpisodeTitle, "alpha", 1);
AnimatorSet set = new AnimatorSet();
set.playSequentially(verticalMarquee, fadeOut, fadeBackIn);
set.start();
@@ -206,9 +173,9 @@ public class CoverFragment extends Fragment {
chapterControlVisible = fm.getItem() != null && fm.getItem().hasChapters();
}
int newVisibility = chapterControlVisible ? View.VISIBLE : View.GONE;
- if (chapterControl.getVisibility() != newVisibility) {
- chapterControl.setVisibility(newVisibility);
- ObjectAnimator.ofFloat(chapterControl,
+ if (viewBinding.chapterButton.getVisibility() != newVisibility) {
+ viewBinding.chapterButton.setVisibility(newVisibility);
+ ObjectAnimator.ofFloat(viewBinding.chapterButton,
"alpha",
chapterControlVisible ? 0 : 1,
chapterControlVisible ? 1 : 0)
@@ -220,10 +187,10 @@ public class CoverFragment extends Fragment {
if (chapterIndex > -1) {
if (media.getPosition() > media.getDuration() || chapterIndex >= media.getChapters().size() - 1) {
displayedChapterIndex = media.getChapters().size() - 1;
- butNextChapter.setVisibility(View.INVISIBLE);
+ viewBinding.butNextChapter.setVisibility(View.INVISIBLE);
} else {
displayedChapterIndex = chapterIndex;
- butNextChapter.setVisibility(View.VISIBLE);
+ viewBinding.butNextChapter.setVisibility(View.VISIBLE);
}
}
@@ -266,13 +233,6 @@ public class CoverFragment extends Fragment {
}
@Override
- public void onDestroy() {
- super.onDestroy();
- // prevent memory leaks
- root = null;
- }
-
- @Override
public void onStart() {
super.onStart();
controller = new PlaybackController(getActivity()) {
@@ -313,91 +273,51 @@ public class CoverFragment extends Fragment {
.transform(new FitCenter(),
new RoundedCorners((int) (16 * getResources().getDisplayMetrics().density)));
- RequestBuilder<Drawable> cover = Glide.with(this)
- .load(media.getImageLocation())
- .error(Glide.with(this)
- .load(ImageResourceUtils.getFallbackImageLocation(media))
- .apply(options))
- .apply(options);
+ RequestBuilder<Drawable> cover = Glide.with(this)
+ .load(media.getImageLocation())
+ .error(Glide.with(this)
+ .load(ImageResourceUtils.getFallbackImageLocation(media))
+ .apply(options))
+ .apply(options);
if (displayedChapterIndex == -1 || media == null || media.getChapters() == null
|| TextUtils.isEmpty(media.getChapters().get(displayedChapterIndex).getImageUrl())) {
- cover.into(imgvCover);
+ cover.into(viewBinding.imgvCover);
} else {
Glide.with(this)
.load(EmbeddedChapterImage.getModelFor(media, displayedChapterIndex))
.apply(options)
.thumbnail(cover)
.error(cover)
- .into(imgvCover);
+ .into(viewBinding.imgvCover);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
-
configureForOrientation(newConfig);
}
- public float convertDpToPixel(float dp) {
- Context context = this.getActivity().getApplicationContext();
- return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
- }
-
private void configureForOrientation(Configuration newConfig) {
- LinearLayout mainContainer = getView().findViewById(R.id.cover_fragment);
- LinearLayout textContainer = getView().findViewById(R.id.cover_fragment_text_container);
+ boolean isPortrait = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
- LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imgvCover.getLayoutParams();
- LinearLayout.LayoutParams textParams = (LinearLayout.LayoutParams) textContainer.getLayoutParams();
- double ratio = (float) newConfig.screenHeightDp / (float) newConfig.screenWidthDp;
+ viewBinding.coverFragment.setOrientation(isPortrait ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
- boolean spacerVisible = true;
- ViewGroup detailsParent = (ViewGroup) getView();
- int detailsWidth = ViewGroup.LayoutParams.MATCH_PARENT;
-
- if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
- double percentageWidth = 0.8;
- if (ratio <= SIXTEEN_BY_NINE) {
- percentageWidth = (ratio / SIXTEEN_BY_NINE) * percentageWidth * 0.8;
- }
- mainContainer.setOrientation(LinearLayout.VERTICAL);
- if (newConfig.screenWidthDp > 0) {
- params.width = (int) (convertDpToPixel(newConfig.screenWidthDp) * percentageWidth);
- params.height = params.width;
- textParams.weight = 0;
- imgvCover.setLayoutParams(params);
- }
+ if (isPortrait) {
+ viewBinding.coverHolder.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1));
+ viewBinding.coverFragmentTextContainer.setLayoutParams(
+ new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
} else {
- double percentageHeight = ratio * 0.6;
- mainContainer.setOrientation(LinearLayout.HORIZONTAL);
- if (newConfig.screenHeightDp > 0) {
- params.height = (int) (convertDpToPixel(newConfig.screenHeightDp) * percentageHeight);
- params.width = params.height;
- textParams.weight = 1;
- imgvCover.setLayoutParams(params);
- }
-
- spacerVisible = false;
- detailsParent = textContainer;
- detailsWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
+ viewBinding.coverHolder.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, 1));
+ viewBinding.coverFragmentTextContainer.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, 1));
}
- if (displayedChapterIndex == -1) {
- detailsWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
- }
-
- spacer.setVisibility(spacerVisible ? View.VISIBLE : View.GONE);
- counterweight.setVisibility(spacerVisible ? View.VISIBLE : View.GONE);
- LinearLayout.LayoutParams wrapHeight =
- new LinearLayout.LayoutParams(detailsWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
- episodeDetails.setLayoutParams(wrapHeight);
- getView().findViewById(R.id.vertical_divider).setVisibility(spacerVisible ? View.GONE : View.VISIBLE);
-
- if (episodeDetails.getParent() != detailsParent) {
- ((ViewGroup) episodeDetails.getParent()).removeView(episodeDetails);
- detailsParent.addView(episodeDetails);
+ ((ViewGroup) viewBinding.episodeDetails.getParent()).removeView(viewBinding.episodeDetails);
+ if (isPortrait) {
+ viewBinding.coverFragment.addView(viewBinding.episodeDetails);
+ } else {
+ viewBinding.coverFragmentTextContainer.addView(viewBinding.episodeDetails);
}
}