From 467b2ae1a3ac6884dac0581d9620235049258c4a Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 22 Mar 2020 23:07:59 +0100 Subject: Created audio player fragment --- .../danoeh/antennapod/activity/MainActivity.java | 5 + .../antennapod/fragment/AudioPlayerFragment.java | 37 ++++ .../antennapod/fragment/NavDrawerFragment.java | 1 + app/src/main/res/layout/audioplayer_fragment.xml | 233 +++++++++++++++++++++ core/src/main/res/values/arrays.xml | 1 + 5 files changed, 277 insertions(+) create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java create mode 100644 app/src/main/res/layout/audioplayer_fragment.xml diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 6dab5ab45..35328f0c3 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -31,6 +31,7 @@ import de.danoeh.antennapod.core.util.Flavors; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.dialog.RatingDialog; import de.danoeh.antennapod.fragment.AddFeedFragment; +import de.danoeh.antennapod.fragment.AudioPlayerFragment; import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; import de.danoeh.antennapod.fragment.ExternalPlayerFragment; @@ -158,6 +159,9 @@ public class MainActivity extends CastEnabledActivity { case QueueFragment.TAG: fragment = new QueueFragment(); break; + case AudioPlayerFragment.TAG: + fragment = new AudioPlayerFragment(); + break; case EpisodesFragment.TAG: fragment = new EpisodesFragment(); break; @@ -305,6 +309,7 @@ public class MainActivity extends CastEnabledActivity { switch (NavDrawerFragment.getLastNavFragment(this)) { case QueueFragment.TAG: case EpisodesFragment.TAG: + case AudioPlayerFragment.TAG: requestCastButton(MenuItem.SHOW_AS_ACTION_IF_ROOM); return retVal; case DownloadsFragment.TAG: diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java new file mode 100644 index 000000000..6b6b07d82 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -0,0 +1,37 @@ +package de.danoeh.antennapod.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import de.danoeh.antennapod.R; + +/** + * Shows the audio player. + */ +public class AudioPlayerFragment extends Fragment { + public static final String TAG = "AudioPlayerFragment"; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + View root = inflater.inflate(R.layout.audioplayer_fragment, container, false); + ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); + + + return root; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + + // So, we certainly *don't* have an options menu, + // but unless we say we do, old options menus sometimes + // persist. mfietz thinks this causes the ActionBar to be invalidated + setHasOptionsMenu(true); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java index 63969345c..0ab6b78b9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -56,6 +56,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli public static final String TAG = "NavDrawerFragment"; public static final String[] NAV_DRAWER_TAGS = { + AudioPlayerFragment.TAG, QueueFragment.TAG, EpisodesFragment.TAG, SubscriptionFragment.TAG, diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml new file mode 100644 index 000000000..bac3cb648 --- /dev/null +++ b/app/src/main/res/layout/audioplayer_fragment.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index dc79905cd..45ea97eb4 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -196,6 +196,7 @@ + Audio player @string/queue_label @string/episodes_label @string/subscriptions_label -- cgit v1.2.3 From 64f1af0d6b01d85d9d4cf14ff21227714a478737 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 00:05:06 +0100 Subject: Copied setup from MediaPlayerActivity to AudioPlayerFragment --- .../antennapod/fragment/AudioPlayerFragment.java | 386 ++++++++++++++++++++- app/src/main/res/layout/audioplayer_fragment.xml | 1 + .../core/util/playback/PlaybackController.java | 8 +- 3 files changed, 385 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 6b6b07d82..222daf059 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -1,37 +1,411 @@ package de.danoeh.antennapod.fragment; +import android.content.Context; +import android.content.SharedPreferences; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.SeekBar; +import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.ViewPager; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MediaplayerActivity; +import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; +import de.danoeh.antennapod.core.preferences.PlaybackPreferences; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.playback.PlaybackService; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.IntentUtils; +import de.danoeh.antennapod.core.util.TimeSpeedConverter; +import de.danoeh.antennapod.core.util.playback.Playable; +import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.VariableSpeedDialog; +import de.danoeh.antennapod.view.PagerIndicatorView; +import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.text.DecimalFormat; /** * Shows the audio player. */ -public class AudioPlayerFragment extends Fragment { +public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarChangeListener { public static final String TAG = "AudioPlayerFragment"; + private static final int POS_COVER = 0; + private static final int POS_DESCR = 1; + private static final int POS_CHAPTERS = 2; + private static final int NUM_CONTENT_FRAGMENTS = 3; + private static final String PREFS = "AudioPlayerFragmentPreferences"; + private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft"; + private static final float EPSILON = 0.001f; + + PlaybackSpeedIndicatorView butPlaybackSpeed; + TextView txtvPlaybackSpeed; + private ViewPager pager; + private PagerIndicatorView pageIndicator; + private AudioPlayerPagerAdapter pagerAdapter; + private TextView txtvPosition; + private TextView txtvLength; + private SeekBar sbPosition; + private ImageButton butRev; + private TextView txtvRev; + private ImageButton butPlay; + private ImageButton butFF; + private TextView txtvFF; + private ImageButton butSkip; + + private PlaybackController controller; + private boolean showTimeLeft; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.audioplayer_fragment, container, false); - ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); + Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setTitle(""); + ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); + + butPlaybackSpeed = root.findViewById(R.id.butPlaybackSpeed); + txtvPlaybackSpeed = root.findViewById(R.id.txtvPlaybackSpeed); + sbPosition = root.findViewById(R.id.sbPosition); + txtvPosition = root.findViewById(R.id.txtvPosition); + txtvLength = root.findViewById(R.id.txtvLength); + butRev = root.findViewById(R.id.butRev); + txtvRev = root.findViewById(R.id.txtvRev); + butPlay = root.findViewById(R.id.butPlay); + butFF = root.findViewById(R.id.butFF); + txtvFF = root.findViewById(R.id.txtvFF); + butSkip = root.findViewById(R.id.butSkip); + setupLengthTextView(); + setupControlButtons(); + setupPlaybackSpeedButton(); + txtvRev.setText(String.valueOf(UserPreferences.getRewindSecs())); + txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs())); + sbPosition.setOnSeekBarChangeListener(this); + pager = root.findViewById(R.id.pager); + pagerAdapter = new AudioPlayerPagerAdapter(getFragmentManager()); + pager.setAdapter(pagerAdapter); + pageIndicator = root.findViewById(R.id.page_indicator); + pageIndicator.setViewPager(pager); + pageIndicator.setOnClickListener(v -> + pager.setCurrentItem((pager.getCurrentItem() + 1) % pager.getChildCount())); return root; } + private void setupControlButtons() { + butRev.setOnClickListener(v -> { + if (controller != null) { + int curr = controller.getPosition(); + controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000); + } + }); + butRev.setOnLongClickListener(v -> { + //showSkipPreference(MediaplayerActivity.this, MediaplayerActivity.SkipDirection.SKIP_REWIND); + return true; + }); + butPlay.setOnClickListener(v -> { + if (controller != null) { + controller.init(); + controller.playPause(); + } + }); + butFF.setOnClickListener(v -> { + if (controller != null) { + int curr = controller.getPosition(); + controller.seekTo(curr + UserPreferences.getFastForwardSecs() * 1000); + } + }); + butFF.setOnLongClickListener(v -> { + //showSkipPreference(MediaplayerActivity.this, MediaplayerActivity.SkipDirection.SKIP_FORWARD); + return false; + }); + butSkip.setOnClickListener(v -> + IntentUtils.sendLocalBroadcast(getActivity(), PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); + } + + private void setupLengthTextView() { + SharedPreferences prefs = getContext().getSharedPreferences(PREFS, Context.MODE_PRIVATE); + showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); + txtvLength.setOnClickListener(v -> { + if (controller == null) { + return; + } + showTimeLeft = !showTimeLeft; + prefs.edit().putBoolean(PREF_SHOW_TIME_LEFT, showTimeLeft).apply(); + updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration())); + }); + } + + private void setupPlaybackSpeedButton() { + butPlaybackSpeed.setOnClickListener(v -> { + if (controller == null) { + return; + } + if (!controller.canSetPlaybackSpeed()) { + VariableSpeedDialog.showGetPluginDialog(getContext()); + return; + } + float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); + float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier(); + + int newSpeedIndex = 0; + while (newSpeedIndex < availableSpeeds.length && availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) { + newSpeedIndex++; + } + + float newSpeed; + if (availableSpeeds.length == 0) { + newSpeed = 1.0f; + } else if (newSpeedIndex == availableSpeeds.length) { + newSpeed = availableSpeeds[0]; + } else { + newSpeed = availableSpeeds[newSpeedIndex]; + } + + PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed); + UserPreferences.setPlaybackSpeed(newSpeed); + controller.setPlaybackSpeed(newSpeed); + updateUi(); + }); + butPlaybackSpeed.setOnLongClickListener(v -> { + VariableSpeedDialog.showDialog(getContext()); + return true; + }); + butPlaybackSpeed.setVisibility(View.VISIBLE); + txtvPlaybackSpeed.setVisibility(View.VISIBLE); + } + + protected void updatePlaybackSpeedButton() { + if (butPlaybackSpeed == null || controller == null) { + return; + } + float speed = 1.0f; + if (controller.canSetPlaybackSpeed()) { + speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(controller.getMedia()); + } + String speedStr = new DecimalFormat("0.00").format(speed); + txtvPlaybackSpeed.setText(speedStr); + butPlaybackSpeed.setSpeed(speed); + butPlaybackSpeed.setAlpha(controller.canSetPlaybackSpeed() ? 1.0f : 0.5f); + butPlaybackSpeed.setVisibility(View.VISIBLE); + txtvPlaybackSpeed.setVisibility(View.VISIBLE); + } + + private PlaybackController newPlaybackController() { + return new PlaybackController(getActivity(), false) { + + @Override + public void setupGUI() { + updateUi(); + } + + @Override + public void onBufferStart() { + //MediaplayerActivity.this.onBufferStart(); + } + + @Override + public void onBufferEnd() { + //MediaplayerActivity.this.onBufferEnd(); + } + + @Override + public void onBufferUpdate(float progress) { + //MediaplayerActivity.this.onBufferUpdate(progress); + } + + @Override + public void handleError(int code) { + //MediaplayerActivity.this.handleError(code); + } + + @Override + public void onReloadNotification(int code) { + //MediaplayerActivity.this.onReloadNotification(code); + } + + @Override + public void onSleepTimerUpdate() { + getActivity().invalidateOptionsMenu(); + } + + @Override + public ImageButton getPlayButton() { + return butPlay; + } + + @Override + public void postStatusMsg(int msg, boolean showToast) { + //MediaplayerActivity.this.postStatusMsg(msg, showToast); + } + + @Override + public void clearStatusMsg() { + //MediaplayerActivity.this.clearStatusMsg(); + } + + @Override + public boolean loadMediaInfo() { + updateUi(); + return true; + }/* + + @Override + public void onServiceQueried() { + MediaplayerActivity.this.onServiceQueried(); + } + + @Override + public void onShutdownNotification() { + finish(); + } + + @Override + public void onPlaybackEnd() { + finish(); + }*/ + + @Override + public void onPlaybackSpeedChange() { + updatePlaybackSpeedButton(); + } + + @Override + public void onSetSpeedAbilityChanged() { + updatePlaybackSpeedButton(); + } + }; + } + + private void updateUi() { + if (controller == null) { + return; + } + updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration())); + updatePlaybackSpeedButton(); + getActivity().invalidateOptionsMenu(); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - - // So, we certainly *don't* have an options menu, - // but unless we say we do, old options menus sometimes - // persist. mfietz thinks this causes the ActionBar to be invalidated setHasOptionsMenu(true); } + + @Override + public void onStart() { + super.onStart(); + controller = newPlaybackController(); + controller.init(); + updateUi(); + EventBus.getDefault().register(this); + } + + @Override + public void onStop() { + super.onStop(); + controller.release(); + controller = null; + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void updatePosition(PlaybackPositionEvent event) { + if (controller == null || txtvPosition == null || txtvLength == null || sbPosition == null) { + return; + } + + TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); + int currentPosition = converter.convert(event.getPosition()); + int duration = converter.convert(event.getDuration()); + int remainingTime = converter.convert(event.getDuration() - event.getPosition()); + Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition)); + if (currentPosition == PlaybackService.INVALID_TIME || duration == PlaybackService.INVALID_TIME) { + Log.w(TAG, "Could not react to position observer update because of invalid time"); + return; + } + txtvPosition.setText(Converter.getDurationStringLong(currentPosition)); + if (showTimeLeft) { + txtvLength.setText("-" + Converter.getDurationStringLong(remainingTime)); + } else { + txtvLength.setText(Converter.getDurationStringLong(duration)); + } + float progress = ((float) event.getPosition()) / event.getDuration(); + sbPosition.setProgress((int) (progress * sbPosition.getMax())); + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (controller == null || txtvLength == null) { + return; + } + if (fromUser) { + float prog = progress / ((float) seekBar.getMax()); + int duration = controller.getDuration(); + TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); + int position = converter.convert((int) (prog * duration)); + txtvPosition.setText(Converter.getDurationStringLong(position)); + + if (showTimeLeft && prog != 0) { + int timeLeft = converter.convert(duration - (int) (prog * duration)); + String length = "-" + Converter.getDurationStringLong(timeLeft); + txtvLength.setText(length); + } + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + // interrupt position Observer, restart later + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (controller != null) { + float prog = seekBar.getProgress() / ((float) seekBar.getMax()); + controller.seekTo((int) (prog * controller.getDuration())); + } + } + + private static class AudioPlayerPagerAdapter extends FragmentStatePagerAdapter { + private static final String TAG = "AudioPlayerPagerAdapter"; + + public AudioPlayerPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + Log.d(TAG, "getItem(" + position + ")"); + switch (position) { + case POS_COVER: + return new CoverFragment(); + case POS_DESCR: + return new ItemDescriptionFragment(); + case POS_CHAPTERS: + return new ChaptersFragment(); + default: + return null; + } + } + + @Override + public int getCount() { + return NUM_CONTENT_FRAGMENTS; + } + } } diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml index bac3cb648..efd64ef3b 100644 --- a/app/src/main/res/layout/audioplayer_fragment.xml +++ b/app/src/main/res/layout/audioplayer_fragment.xml @@ -84,6 +84,7 @@ android:text="@string/position_default_label" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_micro" + android:background="?android:attr/selectableItemBackground" tools:background="@android:color/holo_green_dark"/> diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 6347f8284..7d47ef6ac 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -599,8 +599,8 @@ public class PlaybackController { public int getPosition() { if (playbackService != null) { return playbackService.getCurrentPosition(); - } else if (media != null) { - return media.getPosition(); + } else if (getMedia() != null) { + return getMedia().getPosition(); } else { return PlaybackService.INVALID_TIME; } @@ -609,8 +609,8 @@ public class PlaybackController { public int getDuration() { if (playbackService != null) { return playbackService.getDuration(); - } else if (media != null) { - return media.getDuration(); + } else if (getMedia() != null) { + return getMedia().getDuration(); } else { return PlaybackService.INVALID_TIME; } -- cgit v1.2.3 From 8cd29de2f4583e6343879012ea8ba63f865adeec Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 00:21:41 +0100 Subject: Extracted skip preference dialog --- .../antennapod/activity/MediaplayerActivity.java | 104 +-------------------- .../antennapod/dialog/SkipPreferenceDialog.java | 58 ++++++++++++ .../antennapod/fragment/AudioPlayerFragment.java | 7 +- .../preferences/PlaybackPreferencesFragment.java | 6 +- 4 files changed, 71 insertions(+), 104 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index c0ba75ba6..4e8269810 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.activity; import android.Manifest; import android.annotation.TargetApi; -import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -35,15 +34,12 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.util.Consumer; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.Flavors; -import de.danoeh.antennapod.core.util.Function; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.ShareUtils; import de.danoeh.antennapod.core.util.StorageUtils; -import de.danoeh.antennapod.core.util.Supplier; import de.danoeh.antennapod.core.util.TimeSpeedConverter; import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; import de.danoeh.antennapod.core.util.playback.ExternalMedia; @@ -52,6 +48,7 @@ import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import de.danoeh.antennapod.dialog.PlaybackControlsDialog; +import de.danoeh.antennapod.dialog.SkipPreferenceDialog; import de.danoeh.antennapod.dialog.SleepTimerDialog; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -198,13 +195,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements onPositionObserverUpdate(); } - private static TextView getTxtvFFFromActivity(MediaplayerActivity activity) { - return activity.txtvFF; - } - private static TextView getTxtvRevFromActivity(MediaplayerActivity activity) { - return activity.txtvRev; - } - private void onSetSpeedAbilityChanged() { Log.d(TAG, "onSetSpeedAbilityChanged()"); updatePlaybackSpeedButton(); @@ -543,92 +533,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements // Only meaningful on AudioplayerActivity, where it is overridden. } - /** - * Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons). - */ - public enum SkipDirection { - SKIP_FORWARD( - UserPreferences::getFastForwardSecs, - MediaplayerActivity::getTxtvFFFromActivity, - UserPreferences::setFastForwardSecs, - R.string.pref_fast_forward), - SKIP_REWIND(UserPreferences::getRewindSecs, - MediaplayerActivity::getTxtvRevFromActivity, - UserPreferences::setRewindSecs, - R.string.pref_rewind); - - private final Supplier getPrefSecsFn; - private final Function getTextViewFn; - private final Consumer setPrefSecsFn; - private final int titleResourceID; - - /** - * Constructor for skip direction enum. Stores references to utility functions and resource - * id's that vary dependending on the direction. - * - * @param getPrefSecsFn Handle to function that retrieves current seconds of the skip delta - * @param getTextViewFn Handle to function that gets the TextView which displays the current skip delta value - * @param setPrefSecsFn Handle to function that sets the preference (setting) for the skip delta value (and optionally updates the button label with the current values) - * @param titleResourceID ID of the resource string with the title for a view - */ - SkipDirection(Supplier getPrefSecsFn, Function getTextViewFn, Consumer setPrefSecsFn, int titleResourceID) { - this.getPrefSecsFn = getPrefSecsFn; - this.getTextViewFn = getTextViewFn; - this.setPrefSecsFn = setPrefSecsFn; - this.titleResourceID = titleResourceID; - } - - - public int getPrefSkipSeconds() { - return(getPrefSecsFn.get()); - } - - /** - * Updates preferences for a forward or backward skip depending on the direction of the instance, optionally updating the UI. - * - * @param seconds Number of seconds to set the preference associated with the direction of the instance. - * @param activity MediaplyerActivity that contains textview to update the display of the skip delta setting (or null if nothing to update) - */ - public void setPrefSkipSeconds(int seconds, @Nullable Activity activity) { - setPrefSecsFn.accept(seconds); - - if (activity != null && activity instanceof MediaplayerActivity) { - TextView tv = getTextViewFn.apply((MediaplayerActivity)activity); - if (tv != null) tv.setText(String.valueOf(seconds)); - } - } - public int getTitleResourceID() { - return titleResourceID; - } - } - - public static void showSkipPreference(Activity activity, SkipDirection direction) { - int checked = 0; - int skipSecs = direction.getPrefSkipSeconds(); - final int[] values = activity.getResources().getIntArray(R.array.seek_delta_values); - final String[] choices = new String[values.length]; - for (int i = 0; i < values.length; i++) { - if (skipSecs == values[i]) { - checked = i; - } - choices[i] = String.valueOf(values[i]) + " " + activity.getString(R.string.time_seconds); - } - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(direction.getTitleResourceID()); - builder.setSingleChoiceItems(choices, checked, null); - builder.setNegativeButton(R.string.cancel_label, null); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - int choice = ((AlertDialog)dialog).getListView().getCheckedItemPosition(); - if (choice < 0 || choice >= values.length) { - System.err.printf("Choice in showSkipPreference is out of bounds %d", choice); - } else { - direction.setPrefSkipSeconds(values[choice], activity); - } - }); - builder.create().show(); - } - void setupGUI() { setContentView(getContentViewResourceId()); sbPosition = findViewById(R.id.sbPosition); @@ -688,7 +592,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if (butRev != null) { butRev.setOnClickListener(v -> onRewind()); butRev.setOnLongClickListener(v -> { - showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_REWIND); + SkipPreferenceDialog.showSkipPreference(MediaplayerActivity.this, + SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev); return true; }); } @@ -698,7 +603,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if (butFF != null) { butFF.setOnClickListener(v -> onFastForward()); butFF.setOnLongClickListener(v -> { - showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_FORWARD); + SkipPreferenceDialog.showSkipPreference(MediaplayerActivity.this, + SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, txtvFF); return false; }); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java new file mode 100644 index 000000000..7bb8f5ad6 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/SkipPreferenceDialog.java @@ -0,0 +1,58 @@ +package de.danoeh.antennapod.dialog; + +import android.content.Context; +import android.widget.TextView; +import androidx.appcompat.app.AlertDialog; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; + +/** + * Shows the dialog that allows setting the skip time. + */ +public class SkipPreferenceDialog { + public static void showSkipPreference(Context context, SkipDirection direction, TextView textView) { + int checked = 0; + + int skipSecs; + if (direction == SkipDirection.SKIP_FORWARD) { + skipSecs = UserPreferences.getFastForwardSecs(); + } else { + skipSecs = UserPreferences.getRewindSecs(); + } + + final int[] values = context.getResources().getIntArray(R.array.seek_delta_values); + final String[] choices = new String[values.length]; + for (int i = 0; i < values.length; i++) { + if (skipSecs == values[i]) { + checked = i; + } + choices[i] = values[i] + " " + context.getString(R.string.time_seconds); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(direction == SkipDirection.SKIP_FORWARD ? R.string.pref_fast_forward : R.string.pref_rewind); + builder.setSingleChoiceItems(choices, checked, null); + builder.setNegativeButton(R.string.cancel_label, null); + builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { + int choice = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); + if (choice < 0 || choice >= values.length) { + System.err.printf("Choice in showSkipPreference is out of bounds %d", choice); + } else { + int seconds = values[choice]; + if (direction == SkipDirection.SKIP_FORWARD) { + UserPreferences.setFastForwardSecs(seconds); + } else { + UserPreferences.setRewindSecs(seconds); + } + if (textView != null) { + textView.setText(String.valueOf(seconds)); + } + } + }); + builder.create().show(); + } + + public enum SkipDirection { + SKIP_FORWARD, SKIP_REWIND + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 222daf059..afeb8bf15 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -28,6 +28,7 @@ import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.TimeSpeedConverter; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.SkipPreferenceDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; import de.danoeh.antennapod.view.PagerIndicatorView; import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView; @@ -113,7 +114,8 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh } }); butRev.setOnLongClickListener(v -> { - //showSkipPreference(MediaplayerActivity.this, MediaplayerActivity.SkipDirection.SKIP_REWIND); + SkipPreferenceDialog.showSkipPreference(getContext(), + SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev); return true; }); butPlay.setOnClickListener(v -> { @@ -129,7 +131,8 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh } }); butFF.setOnLongClickListener(v -> { - //showSkipPreference(MediaplayerActivity.this, MediaplayerActivity.SkipDirection.SKIP_FORWARD); + SkipPreferenceDialog.showSkipPreference(getContext(), + SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, txtvFF); return false; }); butSkip.setOnClickListener(v -> diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java index 34684ac49..6b2255b52 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java @@ -9,11 +9,11 @@ import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MediaplayerActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; +import de.danoeh.antennapod.dialog.SkipPreferenceDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; import de.danoeh.antennapod.preferences.PreferenceControllerFlavorHelper; import java.util.Map; @@ -48,11 +48,11 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat { return true; }); findPreference(PREF_PLAYBACK_REWIND_DELTA_LAUNCHER).setOnPreferenceClickListener(preference -> { - MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_REWIND); + SkipPreferenceDialog.showSkipPreference(activity, SkipPreferenceDialog.SkipDirection.SKIP_REWIND, null); return true; }); findPreference(PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER).setOnPreferenceClickListener(preference -> { - MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_FORWARD); + SkipPreferenceDialog.showSkipPreference(activity, SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, null); return true; }); if (!PictureInPictureUtil.supportsPictureInPicture(activity)) { -- cgit v1.2.3 From 16d0a1befa09aaa40e29ff906bc86f5a1d496fb5 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 00:57:57 +0100 Subject: Added options menu --- .../antennapod/fragment/AudioPlayerFragment.java | 84 +++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index afeb8bf15..7fcb3f973 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -1,15 +1,21 @@ package de.danoeh.antennapod.fragment; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; @@ -17,8 +23,12 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.viewpager.widget.ViewPager; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MediaplayerActivity; +import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.core.event.FavoritesEvent; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import de.danoeh.antennapod.core.feed.Chapter; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -28,8 +38,11 @@ import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.TimeSpeedConverter; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.PlaybackControlsDialog; import de.danoeh.antennapod.dialog.SkipPreferenceDialog; +import de.danoeh.antennapod.dialog.SleepTimerDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; +import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.view.PagerIndicatorView; import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView; import org.greenrobot.eventbus.EventBus; @@ -37,6 +50,7 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.text.DecimalFormat; +import java.util.List; /** * Shows the audio player. @@ -300,6 +314,10 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration())); updatePlaybackSpeedButton(); getActivity().invalidateOptionsMenu(); + + List chapters = controller.getMedia().getChapters(); + boolean hasChapters = chapters != null && !chapters.isEmpty(); + pageIndicator.setDisabledPage(hasChapters ? -1 : 2); } @Override @@ -351,6 +369,11 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh sbPosition.setProgress((int) (progress * sbPosition.getMax())); } + @Subscribe(threadMode = ThreadMode.MAIN) + public void favoritesChanged(FavoritesEvent event) { + getActivity().invalidateOptionsMenu(); + } + @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (controller == null || txtvLength == null) { @@ -384,6 +407,65 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh } } + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + /*if (Flavors.FLAVOR == Flavors.PLAY) { + requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); + }*/ + inflater.inflate(R.menu.mediaplayer, menu); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + if (controller == null) { + return; + } + Playable media = controller.getMedia(); + boolean isFeedMedia = media instanceof FeedMedia; + menu.findItem(R.id.open_feed_item).setVisible(isFeedMedia); + if (isFeedMedia) { + FeedItemMenuHandler.onPrepareMenu(menu, ((FeedMedia) media).getItem()); + } + + menu.findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); + menu.findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (controller == null) { + return false; + } + Playable media = controller.getMedia(); + if (media == null) { + return false; + } + + final @Nullable FeedItem feedItem = (media instanceof FeedMedia) ? ((FeedMedia) media).getItem() : null; + if (feedItem != null && FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), feedItem)) { + return true; + } + switch (item.getItemId()) { + case R.id.disable_sleeptimer_item: // Fall-through + case R.id.set_sleeptimer_item: + new SleepTimerDialog().show(getFragmentManager(), "SleepTimerDialog"); + return true; + case R.id.audio_controls: + PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(false); + dialog.show(getFragmentManager(), "playback_controls"); + return true; + case R.id.open_feed_item: + if (feedItem != null) { + Intent intent = MainActivity.getIntentToOpenFeed(getContext(), feedItem.getFeedId()); + startActivity(intent); + } + return true; + } + return false; + } + private static class AudioPlayerPagerAdapter extends FragmentStatePagerAdapter { private static final String TAG = "AudioPlayerPagerAdapter"; -- cgit v1.2.3 From e417f4a5f8f0a2e53deb5eba7059a83d85432a9e Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 01:46:50 +0100 Subject: Added bottom sheet to activity --- .../danoeh/antennapod/activity/MainActivity.java | 41 ++++++++++++--- .../antennapod/fragment/AudioPlayerFragment.java | 60 +++++++++++----------- .../fragment/ExternalPlayerFragment.java | 10 ++-- .../antennapod/fragment/NavDrawerFragment.java | 1 - app/src/main/res/layout/audioplayer_fragment.xml | 10 ++++ app/src/main/res/layout/main.xml | 48 ++++++++--------- core/src/main/res/values/arrays.xml | 1 - 7 files changed, 101 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 35328f0c3..c8b10751d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -23,6 +23,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import com.bumptech.glide.Glide; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.event.MessageEvent; @@ -34,7 +35,6 @@ import de.danoeh.antennapod.fragment.AddFeedFragment; import de.danoeh.antennapod.fragment.AudioPlayerFragment; import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; -import de.danoeh.antennapod.fragment.ExternalPlayerFragment; import de.danoeh.antennapod.fragment.FeedItemlistFragment; import de.danoeh.antennapod.fragment.NavDrawerFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; @@ -68,6 +68,7 @@ public class MainActivity extends CastEnabledActivity { private DrawerLayout drawerLayout; private View navDrawer; private ActionBarDrawerToggle drawerToggle; + private BottomSheetBehavior sheetBehavior; private long lastBackButtonPressTime = 0; @NonNull @@ -112,15 +113,34 @@ public class MainActivity extends CastEnabledActivity { } } } - ExternalPlayerFragment externalPlayerFragment = new ExternalPlayerFragment(); - transaction.replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG); NavDrawerFragment navDrawerFragment = new NavDrawerFragment(); transaction.replace(R.id.navDrawerFragment, navDrawerFragment, NavDrawerFragment.TAG); - + AudioPlayerFragment audioPlayerFragment = new AudioPlayerFragment(); + transaction.replace(R.id.audioplayerFragment, audioPlayerFragment, AudioPlayerFragment.TAG); transaction.commit(); checkFirstLaunch(); PreferenceUpgrader.checkUpgrades(this); + View bottomSheet = findViewById(R.id.audioplayerFragment); + sheetBehavior = BottomSheetBehavior.from(bottomSheet); + sheetBehavior.setPeekHeight((int) getResources().getDimension(R.dimen.external_player_height)); + sheetBehavior.setHideable(false); + sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View view, int state) { + + } + + @Override + public void onSlide(@NonNull View view, float slideOffset) { + AudioPlayerFragment audioPlayer = + (AudioPlayerFragment) getSupportFragmentManager().findFragmentByTag(AudioPlayerFragment.TAG); + float condensedSlideOffset = Math.max(0.0f, Math.min(0.1f, slideOffset - 0.5f)) / 0.1f; + audioPlayer.getExternalPlayerHolder().setAlpha(1 - condensedSlideOffset); + audioPlayer.getExternalPlayerHolder().setVisibility( + condensedSlideOffset > 0.99f ? View.GONE : View.VISIBLE); + } + }); } @Override @@ -152,6 +172,14 @@ public class MainActivity extends CastEnabledActivity { return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer); } + public void expandBottomSheet() { + sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + } + + public void collapseBottomSheet() { + sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } + public void loadFragment(String tag, Bundle args) { Log.d(TAG, "loadFragment(tag: " + tag + ", args: " + args + ")"); Fragment fragment; @@ -159,9 +187,6 @@ public class MainActivity extends CastEnabledActivity { case QueueFragment.TAG: fragment = new QueueFragment(); break; - case AudioPlayerFragment.TAG: - fragment = new AudioPlayerFragment(); - break; case EpisodesFragment.TAG: fragment = new EpisodesFragment(); break; @@ -344,6 +369,8 @@ public class MainActivity extends CastEnabledActivity { public void onBackPressed() { if (isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); + } else if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { + collapseBottomSheet(); } else if (getSupportFragmentManager().getBackStackEntryCount() != 0) { super.onBackPressed(); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 7fcb3f973..7d8500f44 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -6,17 +6,13 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -55,7 +51,8 @@ import java.util.List; /** * Shows the audio player. */ -public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarChangeListener { +public class AudioPlayerFragment extends Fragment implements + SeekBar.OnSeekBarChangeListener, Toolbar.OnMenuItemClickListener { public static final String TAG = "AudioPlayerFragment"; private static final int POS_COVER = 0; private static final int POS_DESCR = 1; @@ -69,7 +66,6 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh TextView txtvPlaybackSpeed; private ViewPager pager; private PagerIndicatorView pageIndicator; - private AudioPlayerPagerAdapter pagerAdapter; private TextView txtvPosition; private TextView txtvLength; private SeekBar sbPosition; @@ -79,6 +75,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh private ImageButton butFF; private TextView txtvFF; private ImageButton butSkip; + private Toolbar toolbar; private PlaybackController controller; private boolean showTimeLeft; @@ -87,9 +84,16 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.audioplayer_fragment, container, false); - Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar = root.findViewById(R.id.toolbar); toolbar.setTitle(""); - ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); + toolbar.setNavigationOnClickListener(v -> ((MainActivity) getActivity()).collapseBottomSheet()); + toolbar.setOnMenuItemClickListener(this); + setupOptionsMenu(); + + ExternalPlayerFragment externalPlayerFragment = new ExternalPlayerFragment(); + getFragmentManager().beginTransaction() + .replace(R.id.playerFragment, externalPlayerFragment, ExternalPlayerFragment.TAG) + .commit(); butPlaybackSpeed = root.findViewById(R.id.butPlaybackSpeed); txtvPlaybackSpeed = root.findViewById(R.id.txtvPlaybackSpeed); @@ -111,7 +115,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh sbPosition.setOnSeekBarChangeListener(this); pager = root.findViewById(R.id.pager); - pagerAdapter = new AudioPlayerPagerAdapter(getFragmentManager()); + AudioPlayerPagerAdapter pagerAdapter = new AudioPlayerPagerAdapter(getFragmentManager()); pager.setAdapter(pagerAdapter); pageIndicator = root.findViewById(R.id.page_indicator); pageIndicator.setViewPager(pager); @@ -120,6 +124,10 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh return root; } + public View getExternalPlayerHolder() { + return getView().findViewById(R.id.playerFragment); + } + private void setupControlButtons() { butRev.setOnClickListener(v -> { if (controller != null) { @@ -256,7 +264,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh @Override public void onSleepTimerUpdate() { - getActivity().invalidateOptionsMenu(); + setupOptionsMenu(); } @Override @@ -313,7 +321,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh } updatePosition(new PlaybackPositionEvent(controller.getPosition(), controller.getDuration())); updatePlaybackSpeedButton(); - getActivity().invalidateOptionsMenu(); + setupOptionsMenu(); List chapters = controller.getMedia().getChapters(); boolean hasChapters = chapters != null && !chapters.isEmpty(); @@ -324,7 +332,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - setHasOptionsMenu(true); + //setHasOptionsMenu(true); } @Override @@ -371,7 +379,7 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh @Subscribe(threadMode = ThreadMode.MAIN) public void favoritesChanged(FavoritesEvent event) { - getActivity().invalidateOptionsMenu(); + setupOptionsMenu(); } @Override @@ -407,34 +415,26 @@ public class AudioPlayerFragment extends Fragment implements SeekBar.OnSeekBarCh } } - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - /*if (Flavors.FLAVOR == Flavors.PLAY) { - requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - }*/ - inflater.inflate(R.menu.mediaplayer, menu); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); + public void setupOptionsMenu() { + if (toolbar.getMenu().size() == 0) { + toolbar.inflateMenu(R.menu.mediaplayer); + } if (controller == null) { return; } Playable media = controller.getMedia(); boolean isFeedMedia = media instanceof FeedMedia; - menu.findItem(R.id.open_feed_item).setVisible(isFeedMedia); + toolbar.getMenu().findItem(R.id.open_feed_item).setVisible(isFeedMedia); if (isFeedMedia) { - FeedItemMenuHandler.onPrepareMenu(menu, ((FeedMedia) media).getItem()); + FeedItemMenuHandler.onPrepareMenu(toolbar.getMenu(), ((FeedMedia) media).getItem()); } - menu.findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); - menu.findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); + toolbar.getMenu().findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); + toolbar.getMenu().findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onMenuItemClick(MenuItem item) { if (controller == null) { return false; } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index ce2232a55..fa753aac8 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -1,9 +1,7 @@ package de.danoeh.antennapod.fragment; import android.content.Intent; -import android.os.Build; import android.os.Bundle; -import androidx.core.app.ActivityOptionsCompat; import androidx.fragment.app.Fragment; import android.util.Log; import android.view.LayoutInflater; @@ -18,6 +16,7 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.glide.ApGlideSettings; @@ -69,13 +68,10 @@ public class ExternalPlayerFragment extends Fragment { Log.d(TAG, "layoutInfo was clicked"); if (controller != null && controller.getMedia() != null) { - Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia()); - if (controller.getMedia().getMediaType() == MediaType.AUDIO) { - ActivityOptionsCompat options = ActivityOptionsCompat - .makeSceneTransitionAnimation(getActivity(), imgvCover, "coverTransition"); - startActivity(intent, options.toBundle()); + ((MainActivity) getActivity()).expandBottomSheet(); } else { + Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia()); startActivity(intent); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java index 0ab6b78b9..63969345c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -56,7 +56,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli public static final String TAG = "NavDrawerFragment"; public static final String[] NAV_DRAWER_TAGS = { - AudioPlayerFragment.TAG, QueueFragment.TAG, EpisodesFragment.TAG, SubscriptionFragment.TAG, diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml index efd64ef3b..17352b93d 100644 --- a/app/src/main/res/layout/audioplayer_fragment.xml +++ b/app/src/main/res/layout/audioplayer_fragment.xml @@ -12,6 +12,7 @@ android:minHeight="?attr/actionBarSize" android:theme="?attr/actionBarTheme" android:layout_alignParentTop="true" + app:navigationIcon="?homeAsUpIndicator" android:id="@+id/toolbar"/> + + - - - + android:layout_height="match_parent"> - + + + + android:id="@+id/navDrawerFragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginEnd="24dp" + android:layout_marginRight="24dp" + android:layout_gravity="start" + android:orientation="vertical" /> \ No newline at end of file diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 45ea97eb4..dc79905cd 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -196,7 +196,6 @@ - Audio player @string/queue_label @string/episodes_label @string/subscriptions_label -- cgit v1.2.3 From cc3e39a2231d213c7f08ae901590b7dcbcf9d37d Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 10:46:55 +0100 Subject: Lock bottom sheet when playing video --- .../danoeh/antennapod/activity/MainActivity.java | 15 ++-- .../antennapod/fragment/AudioPlayerFragment.java | 4 +- .../fragment/ExternalPlayerFragment.java | 6 +- .../view/LockableBottomSheetBehavior.java | 88 ++++++++++++++++++++++ app/src/main/res/layout/main.xml | 3 +- 5 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index c8b10751d..05b167201 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -42,6 +42,7 @@ import de.danoeh.antennapod.fragment.QueueFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.fragment.TransitionEffect; import de.danoeh.antennapod.preferences.PreferenceUpgrader; +import de.danoeh.antennapod.view.LockableBottomSheetBehavior; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.Validate; import org.greenrobot.eventbus.EventBus; @@ -68,7 +69,7 @@ public class MainActivity extends CastEnabledActivity { private DrawerLayout drawerLayout; private View navDrawer; private ActionBarDrawerToggle drawerToggle; - private BottomSheetBehavior sheetBehavior; + private LockableBottomSheetBehavior sheetBehavior; private long lastBackButtonPressTime = 0; @NonNull @@ -122,7 +123,7 @@ public class MainActivity extends CastEnabledActivity { checkFirstLaunch(); PreferenceUpgrader.checkUpgrades(this); View bottomSheet = findViewById(R.id.audioplayerFragment); - sheetBehavior = BottomSheetBehavior.from(bottomSheet); + sheetBehavior = (LockableBottomSheetBehavior) BottomSheetBehavior.from(bottomSheet); sheetBehavior.setPeekHeight((int) getResources().getDimension(R.dimen.external_player_height)); sheetBehavior.setHideable(false); sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @@ -172,12 +173,8 @@ public class MainActivity extends CastEnabledActivity { return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer); } - public void expandBottomSheet() { - sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - } - - public void collapseBottomSheet() { - sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + public LockableBottomSheetBehavior getBottomSheet() { + return sheetBehavior; } public void loadFragment(String tag, Bundle args) { @@ -370,7 +367,7 @@ public class MainActivity extends CastEnabledActivity { if (isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); } else if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { - collapseBottomSheet(); + sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } else if (getSupportFragmentManager().getBackStackEntryCount() != 0) { super.onBackPressed(); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 7d8500f44..d1c073cac 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -18,6 +18,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.viewpager.widget.ViewPager; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.FavoritesEvent; @@ -86,7 +87,8 @@ public class AudioPlayerFragment extends Fragment implements View root = inflater.inflate(R.layout.audioplayer_fragment, container, false); toolbar = root.findViewById(R.id.toolbar); toolbar.setTitle(""); - toolbar.setNavigationOnClickListener(v -> ((MainActivity) getActivity()).collapseBottomSheet()); + toolbar.setNavigationOnClickListener(v -> + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED)); toolbar.setOnMenuItemClickListener(this); setupOptionsMenu(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index fa753aac8..57193e08b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -15,6 +15,7 @@ import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; @@ -69,7 +70,7 @@ public class ExternalPlayerFragment extends Fragment { if (controller != null && controller.getMedia() != null) { if (controller.getMedia().getMediaType() == MediaType.AUDIO) { - ((MainActivity) getActivity()).expandBottomSheet(); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_EXPANDED); } else { Intent intent = PlaybackService.getPlayerActivityIntent(getActivity(), controller.getMedia()); startActivity(intent); @@ -236,8 +237,11 @@ public class ExternalPlayerFragment extends Fragment { fragmentLayout.setVisibility(View.VISIBLE); if (controller != null && controller.isPlayingVideoLocally()) { butPlay.setVisibility(View.GONE); + ((MainActivity) getActivity()).getBottomSheet().setLocked(true); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } else { butPlay.setVisibility(View.VISIBLE); + ((MainActivity) getActivity()).getBottomSheet().setLocked(false); } } else { Log.w(TAG, "loadMediaInfo was called while the media object of playbackService was null!"); diff --git a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java new file mode 100644 index 000000000..f4c073fc6 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java @@ -0,0 +1,88 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import com.google.android.material.bottomsheet.BottomSheetBehavior; + +/** + * Based on https://stackoverflow.com/a/40798214 + */ +public class LockableBottomSheetBehavior extends BottomSheetBehavior { + + private boolean mLocked = false; + + public LockableBottomSheetBehavior() {} + + public LockableBottomSheetBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setLocked(boolean locked) { + mLocked = locked; + } + + @Override + public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { + boolean handled = false; + + if (!mLocked) { + handled = super.onInterceptTouchEvent(parent, child, event); + } + + return handled; + } + + @Override + public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { + boolean handled = false; + + if (!mLocked) { + handled = super.onTouchEvent(parent, child, event); + } + + return handled; + } + + @Override + public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, + View target, int nestedScrollAxes) { + boolean handled = false; + + if (!mLocked) { + handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); + } + + return handled; + } + + @Override + public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, + int dx, int dy, int[] consumed) { + if (!mLocked) { + super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); + } + } + + @Override + public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) { + if (!mLocked) { + super.onStopNestedScroll(coordinatorLayout, child, target); + } + } + + @Override + public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, + float velocityX, float velocityY) { + boolean handled = false; + + if (!mLocked) { + handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); + } + + return handled; + + } +} diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml index 90088b792..60b9623bc 100644 --- a/app/src/main/res/layout/main.xml +++ b/app/src/main/res/layout/main.xml @@ -22,11 +22,12 @@ tools:background="@android:color/holo_red_dark" /> + app:layout_behavior="de.danoeh.antennapod.view.LockableBottomSheetBehavior" /> -- cgit v1.2.3 From 6b79daacfe72b54bf48f46fdfde7b8a2515e3a58 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 11:08:19 +0100 Subject: Converted chapters list to RecyclerView This fixes scrolling in bottom sheet --- .../antennapod/adapter/ChaptersListAdapter.java | 104 ++++++++++----------- .../antennapod/fragment/ChaptersFragment.java | 66 +++++++------ 2 files changed, 82 insertions(+), 88 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java index 1171acaa5..8b0aa537e 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java @@ -2,40 +2,38 @@ package de.danoeh.antennapod.adapter; import android.content.Context; import android.text.TextUtils; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.FitCenter; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.Chapter; -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.Converter; import de.danoeh.antennapod.core.util.EmbeddedChapterImage; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.ThemeUtils; import de.danoeh.antennapod.core.util.playback.Playable; -public class ChaptersListAdapter extends ArrayAdapter { - private static final String TAG = "ChapterListAdapter"; - +public class ChaptersListAdapter extends RecyclerView.Adapter { private Playable media; private final Callback callback; + private final Context context; private int currentChapterIndex = -1; private boolean hasImages = false; - public ChaptersListAdapter(Context context, int textViewResourceId, Callback callback) { - super(context, textViewResourceId); + public ChaptersListAdapter(Context context, Callback callback) { this.callback = callback; + this.context = context; } public void setMedia(Playable media) { @@ -51,34 +49,10 @@ public class ChaptersListAdapter extends ArrayAdapter { notifyDataSetChanged(); } - @NonNull - @Override - public View getView(final int position, View convertView, @NonNull ViewGroup parent) { - Holder holder; + @Override + public void onBindViewHolder(@NonNull ChapterHolder holder, int position) { Chapter sc = getItem(position); - - // Inflate Layout - if (convertView == null) { - holder = new Holder(); - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.simplechapter_item, parent, false); - holder.view = convertView; - holder.title = convertView.findViewById(R.id.txtvTitle); - holder.start = convertView.findViewById(R.id.txtvStart); - holder.link = convertView.findViewById(R.id.txtvLink); - holder.image = convertView.findViewById(R.id.imgvCover); - holder.duration = convertView.findViewById(R.id.txtvDuration); - holder.secondaryActionButton = convertView.findViewById(R.id.secondaryActionButton); - holder.secondaryActionIcon = convertView.findViewById(R.id.secondaryActionIcon); - convertView.setTag(holder); - } else { - holder = (Holder) convertView.getTag(); - - } - holder.title.setText(sc.getTitle()); holder.start.setText(Converter.getDurationStringLong((int) sc .getStart())); @@ -89,7 +63,7 @@ public class ChaptersListAdapter extends ArrayAdapter { } else { duration = media.getDuration() - sc.getStart(); } - holder.duration.setText(getContext().getString(R.string.chapter_duration, + holder.duration.setText(context.getString(R.string.chapter_duration, Converter.getDurationStringLong((int) duration))); if (sc.getLink() == null) { @@ -97,9 +71,9 @@ public class ChaptersListAdapter extends ArrayAdapter { } else { holder.link.setVisibility(View.VISIBLE); holder.link.setText(sc.getLink()); - holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), sc.getLink())); + holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(context, sc.getLink())); } - holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(getContext(), R.attr.av_play)); + holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_play)); holder.secondaryActionButton.setOnClickListener(v -> { if (callback != null) { callback.onPlayChapterButtonClicked(position); @@ -107,47 +81,42 @@ public class ChaptersListAdapter extends ArrayAdapter { }); if (position == currentChapterIndex) { - int playingBackGroundColor = ThemeUtils.getColorFromAttr(getContext(), R.attr.currently_playing_background); - holder.view.setBackgroundColor(playingBackGroundColor); + int playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background); + holder.itemView.setBackgroundColor(playingBackGroundColor); } else { - holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent)); + holder.itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent)); } if (hasImages) { holder.image.setVisibility(View.VISIBLE); if (TextUtils.isEmpty(sc.getImageUrl())) { - Glide.with(getContext()).clear(holder.image); + Glide.with(context).clear(holder.image); } else { - Glide.with(getContext()) + Glide.with(context) .load(EmbeddedChapterImage.getModelFor(media, position)) .apply(new RequestOptions() .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) .dontAnimate() .transforms(new FitCenter(), new RoundedCorners((int) - (4 * getContext().getResources().getDisplayMetrics().density)))) + (4 * context.getResources().getDisplayMetrics().density)))) .into(holder.image); } } else { holder.image.setVisibility(View.GONE); } - - return convertView; } - static class Holder { - View view; - TextView title; - TextView start; - TextView link; - TextView duration; - ImageView image; - View secondaryActionButton; - ImageView secondaryActionIcon; + @NonNull + @Override + public ChapterHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(context); + return new ChapterHolder(inflater.inflate(R.layout.simplechapter_item, parent, false)); } @Override - public int getCount() { + public int getItemCount() { if (media == null || media.getChapters() == null) { + Log.d("aaaaa", "0"); return 0; } // ignore invalid chapters @@ -157,9 +126,31 @@ public class ChaptersListAdapter extends ArrayAdapter { counter++; } } + Log.d("aaaaa", "0"+counter); return counter; } + static class ChapterHolder extends RecyclerView.ViewHolder { + final TextView title; + final TextView start; + final TextView link; + final TextView duration; + final ImageView image; + final View secondaryActionButton; + final ImageView secondaryActionIcon; + + public ChapterHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.txtvTitle); + start = itemView.findViewById(R.id.txtvStart); + link = itemView.findViewById(R.id.txtvLink); + image = itemView.findViewById(R.id.imgvCover); + duration = itemView.findViewById(R.id.txtvDuration); + secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton); + secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon); + } + } + public void notifyChapterChanged(int newChapterIndex) { currentChapterIndex = newChapterIndex; notifyDataSetChanged(); @@ -169,7 +160,6 @@ public class ChaptersListAdapter extends ArrayAdapter { return media.getDuration() > 0 && media.getDuration() < c.getStart(); } - @Override public Chapter getItem(int position) { int i = 0; for (Chapter chapter : media.getChapters()) { @@ -181,7 +171,7 @@ public class ChaptersListAdapter extends ArrayAdapter { } } } - return super.getItem(position); + return null; } public interface Callback { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java index 9940ccbdd..0aba568d1 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -1,24 +1,24 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; -import androidx.fragment.app.ListFragment; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; -import android.widget.ListView; - -import de.danoeh.antennapod.core.util.ChapterUtils; -import java.util.List; -import java.util.ListIterator; - +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.ChaptersListAdapter; -import de.danoeh.antennapod.adapter.QueueRecyclerAdapter; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.service.playback.PlayerStatus; +import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; - import de.danoeh.antennapod.view.EmptyViewHandler; import io.reactivex.Maybe; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -28,38 +28,43 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; -public class ChaptersFragment extends ListFragment { +public class ChaptersFragment extends Fragment { private static final String TAG = "ChaptersFragment"; private ChaptersListAdapter adapter; private PlaybackController controller; private Disposable disposable; private int focusedChapter = -1; private Playable media; + private LinearLayoutManager layoutManager; + @Nullable @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - // add padding - final ListView lv = getListView(); - lv.setClipToPadding(false); - final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding); - lv.setPadding(0, vertPadding, 0, vertPadding); - - EmptyViewHandler emptyView = new EmptyViewHandler(getContext()); - emptyView.attachToListView(lv); - emptyView.setIcon(R.attr.ic_bookmark); - emptyView.setTitle(R.string.no_chapters_head_label); - emptyView.setMessage(R.string.no_chapters_label); - - adapter = new ChaptersListAdapter(getActivity(), 0, pos -> { + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.simple_list_fragment, container, false); + root.findViewById(R.id.toolbar).setVisibility(View.GONE); + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + layoutManager = new LinearLayoutManager(getActivity()); + recyclerView.setLayoutManager(layoutManager); + recyclerView.setHasFixedSize(true); + recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + + adapter = new ChaptersListAdapter(getActivity(), pos -> { if (controller.getStatus() != PlayerStatus.PLAYING) { controller.playPause(); } - Chapter chapter = (Chapter) getListAdapter().getItem(pos); + Chapter chapter = adapter.getItem(pos); controller.seekToChapter(chapter); updateChapterSelection(pos); }); - setListAdapter(adapter); + recyclerView.setAdapter(adapter); + + EmptyViewHandler emptyView = new EmptyViewHandler(getContext()); + emptyView.attachToRecyclerView(recyclerView); + emptyView.setIcon(R.attr.ic_bookmark); + emptyView.setTitle(R.string.no_chapters_head_label); + emptyView.setMessage(R.string.no_chapters_label); + + return root; } @Override @@ -136,7 +141,6 @@ public class ChaptersFragment extends ListFragment { return; } adapter.setMedia(media); - adapter.notifyDataSetChanged(); int positionOfCurrentChapter = getCurrentChapter(media); updateChapterSelection(positionOfCurrentChapter); } @@ -149,9 +153,9 @@ public class ChaptersFragment extends ListFragment { if (position != -1 && focusedChapter != position) { focusedChapter = position; adapter.notifyChapterChanged(focusedChapter); - if (getListView().getFirstVisiblePosition() >= position - || getListView().getLastVisiblePosition() <= position) { - getListView().setSelectionFromTop(position, 100); + if (layoutManager.findFirstCompletelyVisibleItemPosition() >= position + || layoutManager.findLastCompletelyVisibleItemPosition() <= position) { + layoutManager.scrollToPositionWithOffset(position, 100); } } } -- cgit v1.2.3 From 5ad7228b4e8650d1fa84bf28db8d810dd0b4aebf Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 14:05:11 +0100 Subject: Going down the BottomSheetBehavior rabbit hole... BottomSheetBehavior only supports one scrolling child. Add support for a ViewPager. ViewPager.getChildAt sometimes does not match the actual position. Make sure that it keeps all children using setOffscreenPageLimit --- .../bottomsheet/ViewPagerBottomSheetBehavior.java | 75 ++++++++++++++++++++++ .../antennapod/adapter/ChaptersListAdapter.java | 3 - .../antennapod/fragment/AudioPlayerFragment.java | 12 +++- .../fragment/ItemDescriptionFragment.java | 6 +- .../view/LockableBottomSheetBehavior.java | 22 +++---- .../main/res/layout/item_description_fragment.xml | 11 ++++ 6 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java create mode 100644 app/src/main/res/layout/item_description_fragment.xml diff --git a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java new file mode 100644 index 000000000..2d211704d --- /dev/null +++ b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java @@ -0,0 +1,75 @@ +package com.google.android.material.bottomsheet; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.ViewCompat; +import androidx.viewpager.widget.ViewPager; + +import java.lang.ref.WeakReference; + +/** + * Override {@link #findScrollingChild(View)} to support {@link ViewPager}'s nested scrolling. + * By the way, In order to override package level method and field. + * This class put in the same package path where {@link BottomSheetBehavior} located. + * Source: https://medium.com/@hanru.yeh/funny-solution-that-makes-bottomsheetdialog-support-viewpager-with-nestedscrollingchilds-bfdca72235c3 + */ +public class ViewPagerBottomSheetBehavior extends BottomSheetBehavior { + + public ViewPagerBottomSheetBehavior() { + super(); + } + + public ViewPagerBottomSheetBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + View findScrollingChild(View view) { + if (ViewCompat.isNestedScrollingEnabled(view)) { + return view; + } + + if (view instanceof ViewPager) { + ViewPager viewPager = (ViewPager) view; + View currentViewPagerChild = viewPager.getChildAt(viewPager.getCurrentItem()); + return findScrollingChild(currentViewPagerChild); + } else if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + for (int i = 0, count = group.getChildCount(); i < count; i++) { + View scrollingChild = findScrollingChild(group.getChildAt(i)); + if (scrollingChild != null) { + return scrollingChild; + } + } + } + return null; + } + + public void updateScrollingChild() { + final View scrollingChild = findScrollingChild(viewRef.get()); + nestedScrollingChildRef = new WeakReference<>(scrollingChild); + } + + /** + * A utility function to get the {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. + * + * @param view The {@link View} with {@link ViewPagerBottomSheetBehavior}. + * @return The {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. + */ + @SuppressWarnings("unchecked") + public static ViewPagerBottomSheetBehavior from(V view) { + ViewGroup.LayoutParams params = view.getLayoutParams(); + if (!(params instanceof CoordinatorLayout.LayoutParams)) { + throw new IllegalArgumentException("The view is not a child of CoordinatorLayout"); + } + CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior(); + if (!(behavior instanceof ViewPagerBottomSheetBehavior)) { + throw new IllegalArgumentException( + "The view is not associated with ViewPagerBottomSheetBehavior"); + } + return (ViewPagerBottomSheetBehavior) behavior; + } +} \ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java index 8b0aa537e..cb72a9150 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.adapter; import android.content.Context; import android.text.TextUtils; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -116,7 +115,6 @@ public class ChaptersListAdapter extends RecyclerView.Adapter ((MainActivity) getActivity()).getBottomSheet().updateScrollingChild()); + } + }); pageIndicator = root.findViewById(R.id.page_indicator); pageIndicator.setViewPager(pager); pageIndicator.setOnClickListener(v -> @@ -468,7 +476,7 @@ public class AudioPlayerFragment extends Fragment implements return false; } - private static class AudioPlayerPagerAdapter extends FragmentStatePagerAdapter { + private static class AudioPlayerPagerAdapter extends FragmentPagerAdapter { private static final String TAG = "AudioPlayerPagerAdapter"; public AudioPlayerPagerAdapter(FragmentManager fm) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java index 256615199..58cc9290c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -10,6 +10,7 @@ import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.Timeline; import de.danoeh.antennapod.view.ShownotesWebView; @@ -35,7 +36,8 @@ public class ItemDescriptionFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, "Creating view"); - webvDescription = new ShownotesWebView(getActivity().getApplicationContext()); + View root = inflater.inflate(R.layout.item_description_fragment, container, false); + webvDescription = root.findViewById(R.id.webview); webvDescription.setTimecodeSelectedListener(time -> { if (controller != null) { controller.seekTo(time); @@ -46,7 +48,7 @@ public class ItemDescriptionFragment extends Fragment { webvDescription.postDelayed(ItemDescriptionFragment.this::restoreFromPreference, 50); }); registerForContextMenu(webvDescription); - return webvDescription; + return root; } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java index f4c073fc6..8e8d98fc9 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java +++ b/app/src/main/java/de/danoeh/antennapod/view/LockableBottomSheetBehavior.java @@ -5,14 +5,13 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.ViewPagerBottomSheetBehavior; /** * Based on https://stackoverflow.com/a/40798214 */ -public class LockableBottomSheetBehavior extends BottomSheetBehavior { - - private boolean mLocked = false; +public class LockableBottomSheetBehavior extends ViewPagerBottomSheetBehavior { + private boolean isLocked = false; public LockableBottomSheetBehavior() {} @@ -21,14 +20,14 @@ public class LockableBottomSheetBehavior extends BottomSheetBeha } public void setLocked(boolean locked) { - mLocked = locked; + isLocked = locked; } @Override public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { boolean handled = false; - if (!mLocked) { + if (!isLocked) { handled = super.onInterceptTouchEvent(parent, child, event); } @@ -39,7 +38,7 @@ public class LockableBottomSheetBehavior extends BottomSheetBeha public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) { boolean handled = false; - if (!mLocked) { + if (!isLocked) { handled = super.onTouchEvent(parent, child, event); } @@ -51,7 +50,7 @@ public class LockableBottomSheetBehavior extends BottomSheetBeha View target, int nestedScrollAxes) { boolean handled = false; - if (!mLocked) { + if (!isLocked) { handled = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @@ -61,14 +60,14 @@ public class LockableBottomSheetBehavior extends BottomSheetBeha @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) { - if (!mLocked) { + if (!isLocked) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); } } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) { - if (!mLocked) { + if (!isLocked) { super.onStopNestedScroll(coordinatorLayout, child, target); } } @@ -78,11 +77,10 @@ public class LockableBottomSheetBehavior extends BottomSheetBeha float velocityX, float velocityY) { boolean handled = false; - if (!mLocked) { + if (!isLocked) { handled = super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); } return handled; - } } diff --git a/app/src/main/res/layout/item_description_fragment.xml b/app/src/main/res/layout/item_description_fragment.xml new file mode 100644 index 000000000..96382eae3 --- /dev/null +++ b/app/src/main/res/layout/item_description_fragment.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file -- cgit v1.2.3 From 11536361c58a54d82f9a85475ac5e8b816090402 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 16:08:18 +0100 Subject: Fixed tests --- .../java/de/test/antennapod/EspressoTestUtils.java | 6 ++++++ .../de/test/antennapod/ui/QueueFragmentTest.java | 7 +++++-- .../bottomsheet/ViewPagerBottomSheetBehavior.java | 23 +--------------------- .../antennapod/fragment/AudioPlayerFragment.java | 8 +++++--- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java index 225f07dfd..beb6ad705 100644 --- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java @@ -32,7 +32,9 @@ import java.util.concurrent.TimeoutException; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; +import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; @@ -193,4 +195,8 @@ public class EspressoTestUtils { } androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } + + public static Matcher actionBarOverflow() { + return allOf(isDisplayed(), withContentDescription("More options")); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java b/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java index 37d76bb6d..ec0d1fa64 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/QueueFragmentTest.java @@ -1,6 +1,7 @@ package de.test.antennapod.ui; import android.content.Intent; +import android.view.View; import androidx.test.espresso.Espresso; import androidx.test.espresso.intent.rule.IntentsTestRule; import androidx.test.runner.AndroidJUnit4; @@ -8,6 +9,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.fragment.QueueFragment; import de.test.antennapod.EspressoTestUtils; +import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -18,6 +20,7 @@ import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.matcher.ViewMatchers.withClassName; import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static de.test.antennapod.NthMatcher.first; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.endsWith; @@ -48,14 +51,14 @@ public class QueueFragmentTest { @Test public void testSortEmptyQueue() { - Espresso.openContextualActionModeOverflowMenu(); + onView(first(EspressoTestUtils.actionBarOverflow())).perform(click()); onView(withText(R.string.sort)).perform(click()); onView(withText(R.string.random)).perform(click()); } @Test public void testKeepEmptyQueueSorted() { - Espresso.openContextualActionModeOverflowMenu(); + onView(first(EspressoTestUtils.actionBarOverflow())).perform(click()); onView(withText(R.string.sort)).perform(click()); onView(withText(R.string.keep_sorted)).perform(click()); } diff --git a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java index 2d211704d..1e76b3bc1 100644 --- a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java +++ b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java @@ -4,7 +4,6 @@ import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; -import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.ViewCompat; import androidx.viewpager.widget.ViewPager; @@ -12,7 +11,7 @@ import java.lang.ref.WeakReference; /** * Override {@link #findScrollingChild(View)} to support {@link ViewPager}'s nested scrolling. - * By the way, In order to override package level method and field. + * In order to override package level method and field. * This class put in the same package path where {@link BottomSheetBehavior} located. * Source: https://medium.com/@hanru.yeh/funny-solution-that-makes-bottomsheetdialog-support-viewpager-with-nestedscrollingchilds-bfdca72235c3 */ @@ -52,24 +51,4 @@ public class ViewPagerBottomSheetBehavior extends BottomSheetBeh final View scrollingChild = findScrollingChild(viewRef.get()); nestedScrollingChildRef = new WeakReference<>(scrollingChild); } - - /** - * A utility function to get the {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. - * - * @param view The {@link View} with {@link ViewPagerBottomSheetBehavior}. - * @return The {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. - */ - @SuppressWarnings("unchecked") - public static ViewPagerBottomSheetBehavior from(V view) { - ViewGroup.LayoutParams params = view.getLayoutParams(); - if (!(params instanceof CoordinatorLayout.LayoutParams)) { - throw new IllegalArgumentException("The view is not a child of CoordinatorLayout"); - } - CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior(); - if (!(behavior instanceof ViewPagerBottomSheetBehavior)) { - throw new IllegalArgumentException( - "The view is not associated with ViewPagerBottomSheetBehavior"); - } - return (ViewPagerBottomSheetBehavior) behavior; - } } \ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 3be79a094..d7925217f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -333,9 +333,11 @@ public class AudioPlayerFragment extends Fragment implements updatePlaybackSpeedButton(); setupOptionsMenu(); - List chapters = controller.getMedia().getChapters(); - boolean hasChapters = chapters != null && !chapters.isEmpty(); - pageIndicator.setDisabledPage(hasChapters ? -1 : 2); + if (controller.getMedia() != null) { + List chapters = controller.getMedia().getChapters(); + boolean hasChapters = chapters != null && !chapters.isEmpty(); + pageIndicator.setDisabledPage(hasChapters ? -1 : 2); + } } @Override -- cgit v1.2.3 From 982ce61b3fd2d27f70c6b595544e7dc51f68b752 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 19:16:18 +0100 Subject: Added basic cast button to AudioPlayerFragment --- .../de/danoeh/antennapod/fragment/AudioPlayerFragment.java | 13 +++++++++++++ .../de/danoeh/antennapod/activity/CastEnabledActivity.java | 13 ++++++++++--- .../antennapod/core/service/playback/PlaybackService.java | 4 +++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index d7925217f..c9322a3a9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -429,6 +429,7 @@ public class AudioPlayerFragment extends Fragment implements public void setupOptionsMenu() { if (toolbar.getMenu().size() == 0) { + //toolbar.inflateMenu(R.menu.cast_enabled); toolbar.inflateMenu(R.menu.mediaplayer); } if (controller == null) { @@ -443,6 +444,18 @@ public class AudioPlayerFragment extends Fragment implements toolbar.getMenu().findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); toolbar.getMenu().findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); + + /*MenuItem mediaRouteButton = toolbar.getMenu().findItem(R.id.media_route_menu_item); + SwitchableMediaRouteActionProvider mediaRouteActionProvider = + CastManager.getInstance().addMediaRouterButton(mediaRouteButton); + CastEnabledActivity.CastButtonVisibilityManager castButtonVisibilityManager = + new CastEnabledActivity.CastButtonVisibilityManager(CastManager.getInstance()); + castButtonVisibilityManager.setMenu(toolbar.getMenu()); + castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled()); + castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider; + castButtonVisibilityManager.setResumed(true); + castButtonVisibilityManager.requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); + mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable());*/ } @Override diff --git a/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java b/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java index e392a50c6..ca5806740 100644 --- a/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java +++ b/app/src/play/java/de/danoeh/antennapod/activity/CastEnabledActivity.java @@ -31,9 +31,8 @@ public abstract class CastEnabledActivity extends AppCompatActivity private CastConsumer castConsumer; private CastManager castManager; - private SwitchableMediaRouteActionProvider mediaRouteActionProvider; - private final CastButtonVisibilityManager castButtonVisibilityManager = new CastButtonVisibilityManager(); + private CastButtonVisibilityManager castButtonVisibilityManager; @Override protected void onCreate(Bundle savedInstanceState) { @@ -59,6 +58,7 @@ public abstract class CastEnabledActivity extends AppCompatActivity }; castManager = CastManager.getInstance(); castManager.addCastConsumer(castConsumer); + castButtonVisibilityManager = new CastButtonVisibilityManager(castManager); castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled()); onCastConnectionChanged(castManager.isConnected()); } @@ -103,6 +103,7 @@ public abstract class CastEnabledActivity extends AppCompatActivity } mediaRouteActionProvider = castManager.addMediaRouterButton(mediaRouteButton); if (mediaRouteActionProvider != null) { + castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider; mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable()); } return true; @@ -162,13 +163,19 @@ public abstract class CastEnabledActivity extends AppCompatActivity castButtonVisibilityManager.requestCastButton(showAsAction); } - private class CastButtonVisibilityManager { + public static class CastButtonVisibilityManager { + private final CastManager castManager; private volatile boolean prefEnabled = false; private volatile boolean viewRequested = false; private volatile boolean resumed = false; private volatile boolean connected = false; private volatile int showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM; private Menu menu; + public SwitchableMediaRouteActionProvider mediaRouteActionProvider; + + public CastButtonVisibilityManager(CastManager castManager) { + this.castManager = castManager; + } public synchronized void setPrefEnabled(boolean newValue) { if (prefEnabled != newValue && resumed && (viewRequested || connected)) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index b92dd217d..9b5931770 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -1218,7 +1218,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { notificationBuilder.setCasting(isCasting); notificationBuilder.updatePosition(getCurrentPosition(), getCurrentPlaybackSpeed()); - Log.d(TAG, "setupNotification: startForeground" + playerStatus); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); startForegroundIfPlaying(playerStatus); @@ -1236,10 +1235,12 @@ public class PlaybackService extends MediaBrowserServiceCompat { } private void startForegroundIfPlaying(@NonNull PlayerStatus status) { + Log.d(TAG, "startForegroundIfPlaying: " + status); if (stateManager.hasReceivedValidStartCommand()) { if (isCasting || status == PlayerStatus.PLAYING || status == PlayerStatus.PREPARING || status == PlayerStatus.SEEKING) { stateManager.startForeground(NOTIFICATION_ID, notificationBuilder.build()); + Log.d(TAG, "foreground"); } else { stateManager.stopForeground(false); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); @@ -1781,6 +1782,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void setIsCasting(boolean isCasting) { PlaybackService.isCasting = isCasting; + stateManager.validStartCommandWasReceived(); } @Override -- cgit v1.2.3 From a989db586a853852549c638d43c425a3463f901d Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 16:09:39 +0100 Subject: Implemented missing PlaybackController state handling --- .../antennapod/activity/MediaplayerActivity.java | 22 +++------- .../activity/MediaplayerInfoActivity.java | 28 ------------ .../antennapod/activity/VideoplayerActivity.java | 14 ------ .../antennapod/fragment/AudioPlayerFragment.java | 50 ++++++++++------------ app/src/main/res/layout/audioplayer_fragment.xml | 9 ++++ .../core/service/playback/PlaybackService.java | 5 --- .../core/util/playback/PlaybackController.java | 16 +------ .../playback/PlaybackServiceFlavorHelper.java | 4 +- 8 files changed, 42 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 4e8269810..973ca6b98 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -137,16 +137,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements return butPlay; } - @Override - public void postStatusMsg(int msg, boolean showToast) { - MediaplayerActivity.this.postStatusMsg(msg, showToast); - } - - @Override - public void clearStatusMsg() { - MediaplayerActivity.this.clearStatusMsg(); - } - @Override public boolean loadMediaInfo() { return MediaplayerActivity.this.loadMediaInfo(); @@ -248,12 +238,16 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements * Should be used to inform the user that the PlaybackService is currently * buffering. */ - protected abstract void onBufferStart(); + protected void onBufferStart() { + + } /** * Should be used to hide the view that was showing the 'buffering'-message. */ - protected abstract void onBufferEnd(); + protected void onBufferEnd() { + + } private void onBufferUpdate(float progress) { if (sbPosition != null) { @@ -468,10 +462,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements */ protected abstract void onAwaitingVideoSurface(); - protected abstract void postStatusMsg(int resId, boolean showToast); - - protected abstract void clearStatusMsg(); - void onPositionObserverUpdate() { if (controller == null || txtvPosition == null || txtvLength == null) { return; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java index 1a7631813..7e4ccbe23 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java @@ -126,24 +126,6 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity { startActivity(new Intent(this, VideoplayerActivity.class)); } - @Override - protected void postStatusMsg(int resId, boolean showToast) { - if (resId == R.string.player_preparing_msg - || resId == R.string.player_seeking_msg - || resId == R.string.player_buffering_msg) { - // TODO Show progress bar here - } - if (showToast) { - Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); - } - } - - @Override - protected void clearStatusMsg() { - // TODO Hide progress bar here - } - - @Override protected void setupGUI() { super.setupGUI(); @@ -199,16 +181,6 @@ public abstract class MediaplayerInfoActivity extends MediaplayerActivity { } } - @Override - protected void onBufferStart() { - postStatusMsg(R.string.player_buffering_msg, false); - } - - @Override - protected void onBufferEnd() { - clearStatusMsg(); - } - public PlaybackController getPlaybackController() { return controller; } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index a1a4e0374..b8a30f994 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -171,20 +171,6 @@ public class VideoplayerActivity extends MediaplayerActivity { } } - @Override - protected void postStatusMsg(int resId, boolean showToast) { - if (resId == R.string.player_preparing_msg) { - progressIndicator.setVisibility(View.VISIBLE); - } else { - progressIndicator.setVisibility(View.INVISIBLE); - } - } - - @Override - protected void clearStatusMsg() { - progressIndicator.setVisibility(View.INVISIBLE); - } - private final View.OnTouchListener onVideoviewTouched = (v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (PictureInPictureUtil.isInPictureInPictureMode(this)) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index c9322a3a9..5b9740154 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -10,9 +10,11 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; +import android.widget.ProgressBar; import android.widget.SeekBar; import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -33,6 +35,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.TimeSpeedConverter; +import de.danoeh.antennapod.core.util.playback.MediaPlayerError; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.dialog.PlaybackControlsDialog; @@ -77,6 +80,7 @@ public class AudioPlayerFragment extends Fragment implements private TextView txtvFF; private ImageButton butSkip; private Toolbar toolbar; + private ProgressBar progressIndicator; private PlaybackController controller; private boolean showTimeLeft; @@ -108,6 +112,7 @@ public class AudioPlayerFragment extends Fragment implements butFF = root.findViewById(R.id.butFF); txtvFF = root.findViewById(R.id.txtvFF); butSkip = root.findViewById(R.id.butSkip); + progressIndicator = root.findViewById(R.id.progLoading); setupLengthTextView(); setupControlButtons(); @@ -249,27 +254,32 @@ public class AudioPlayerFragment extends Fragment implements @Override public void onBufferStart() { - //MediaplayerActivity.this.onBufferStart(); + progressIndicator.setVisibility(View.VISIBLE); } @Override public void onBufferEnd() { - //MediaplayerActivity.this.onBufferEnd(); + progressIndicator.setVisibility(View.GONE); } @Override public void onBufferUpdate(float progress) { - //MediaplayerActivity.this.onBufferUpdate(progress); + sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax())); } @Override public void handleError(int code) { - //MediaplayerActivity.this.handleError(code); - } - - @Override - public void onReloadNotification(int code) { - //MediaplayerActivity.this.onReloadNotification(code); + final AlertDialog.Builder errorDialog = new AlertDialog.Builder(getContext()); + errorDialog.setTitle(R.string.error_label); + errorDialog.setMessage(MediaPlayerError.getErrorString(getContext(), code)); + errorDialog.setNeutralButton(android.R.string.ok, + (dialog, which) -> { + dialog.dismiss(); + ((MainActivity) getActivity()).getBottomSheet() + .setState(BottomSheetBehavior.STATE_COLLAPSED); + } + ); + errorDialog.create().show(); } @Override @@ -282,36 +292,21 @@ public class AudioPlayerFragment extends Fragment implements return butPlay; } - @Override - public void postStatusMsg(int msg, boolean showToast) { - //MediaplayerActivity.this.postStatusMsg(msg, showToast); - } - - @Override - public void clearStatusMsg() { - //MediaplayerActivity.this.clearStatusMsg(); - } - @Override public boolean loadMediaInfo() { updateUi(); return true; - }/* - - @Override - public void onServiceQueried() { - MediaplayerActivity.this.onServiceQueried(); } @Override public void onShutdownNotification() { - finish(); + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); } @Override public void onPlaybackEnd() { - finish(); - }*/ + ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED); + } @Override public void onPlaybackSpeedChange() { @@ -344,7 +339,6 @@ public class AudioPlayerFragment extends Fragment implements public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - //setHasOptionsMenu(true); } @Override diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml index 17352b93d..e1503334c 100644 --- a/app/src/main/res/layout/audioplayer_fragment.xml +++ b/app/src/main/res/layout/audioplayer_fragment.xml @@ -134,6 +134,15 @@ android:layout_centerHorizontal="true" android:layout_centerVertical="true"/> + + Date: Wed, 25 Mar 2020 17:00:48 +0100 Subject: Reworked cast button handling --- .../antennapod/activity/CastEnabledActivity.java | 4 +- .../danoeh/antennapod/activity/MainActivity.java | 24 --- .../antennapod/activity/MediaplayerActivity.java | 4 +- .../antennapod/fragment/AudioPlayerFragment.java | 14 +- .../antennapod/fragment/ItemPagerFragment.java | 3 - app/src/main/res/layout/audioplayer_fragment.xml | 4 +- .../antennapod/activity/CastEnabledActivity.java | 194 ++++----------------- .../core/cast/CastButtonVisibilityManager.java | 120 +++++++++++++ 8 files changed, 165 insertions(+), 202 deletions(-) create mode 100644 core/src/play/java/de/danoeh/antennapod/core/cast/CastButtonVisibilityManager.java diff --git a/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java b/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java index aff1d6ea4..98d506f65 100644 --- a/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java +++ b/app/src/free/java/de/danoeh/antennapod/activity/CastEnabledActivity.java @@ -2,6 +2,8 @@ package de.danoeh.antennapod.activity; import androidx.appcompat.app.AppCompatActivity; +import android.view.Menu; + /** * Activity that allows for showing the MediaRouter button whenever there's a cast device in the * network. @@ -9,7 +11,7 @@ import androidx.appcompat.app.AppCompatActivity; public abstract class CastEnabledActivity extends AppCompatActivity { public static final String TAG = "CastEnabledActivity"; - public final void requestCastButton(int showAsAction) { + public final void requestCastButton(Menu menu) { // no-op } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 05b167201..115114504 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -324,30 +324,6 @@ public class MainActivity extends CastEnabledActivity { Glide.get(this).clearMemory(); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - boolean retVal = super.onCreateOptionsMenu(menu); - if (Flavors.FLAVOR == Flavors.PLAY) { - switch (NavDrawerFragment.getLastNavFragment(this)) { - case QueueFragment.TAG: - case EpisodesFragment.TAG: - case AudioPlayerFragment.TAG: - requestCastButton(MenuItem.SHOW_AS_ACTION_IF_ROOM); - return retVal; - case DownloadsFragment.TAG: - case PlaybackHistoryFragment.TAG: - case AddFeedFragment.TAG: - case SubscriptionFragment.TAG: - return retVal; - default: - requestCastButton(MenuItem.SHOW_AS_ACTION_NEVER); - return retVal; - } - } else { - return retVal; - } - } - @Override public boolean onOptionsItemSelected(MenuItem item) { if (drawerToggle.onOptionsItemSelected(item)) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 973ca6b98..42f750353 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -295,9 +295,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); - if (Flavors.FLAVOR == Flavors.PLAY) { - requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - } + requestCastButton(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.mediaplayer, menu); return true; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 5b9740154..ed136af3c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -22,6 +22,7 @@ import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import com.google.android.material.bottomsheet.BottomSheetBehavior; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.CastEnabledActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.event.FavoritesEvent; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; @@ -423,7 +424,6 @@ public class AudioPlayerFragment extends Fragment implements public void setupOptionsMenu() { if (toolbar.getMenu().size() == 0) { - //toolbar.inflateMenu(R.menu.cast_enabled); toolbar.inflateMenu(R.menu.mediaplayer); } if (controller == null) { @@ -439,17 +439,7 @@ public class AudioPlayerFragment extends Fragment implements toolbar.getMenu().findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); toolbar.getMenu().findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); - /*MenuItem mediaRouteButton = toolbar.getMenu().findItem(R.id.media_route_menu_item); - SwitchableMediaRouteActionProvider mediaRouteActionProvider = - CastManager.getInstance().addMediaRouterButton(mediaRouteButton); - CastEnabledActivity.CastButtonVisibilityManager castButtonVisibilityManager = - new CastEnabledActivity.CastButtonVisibilityManager(CastManager.getInstance()); - castButtonVisibilityManager.setMenu(toolbar.getMenu()); - castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled()); - castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider; - castButtonVisibilityManager.setResumed(true); - castButtonVisibilityManager.requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable());*/ + ((CastEnabledActivity) getActivity()).requestCastButton(toolbar.getMenu()); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java index f251de5ec..39abdeda5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemPagerFragment.java @@ -146,9 +146,6 @@ public class ItemPagerFragment extends Fragment { return; } super.onCreateOptionsMenu(menu, inflater); - if (Flavors.FLAVOR == Flavors.PLAY) { - ((CastEnabledActivity) getActivity()).requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); - } inflater.inflate(R.menu.feeditem_options, menu); if (item.hasMedia()) { FeedItemMenuHandler.onPrepareMenu(menu, item); diff --git a/app/src/main/res/layout/audioplayer_fragment.xml b/app/src/main/res/layout/audioplayer_fragment.xml index e1503334c..905371fa4 100644 --- a/app/src/main/res/layout/audioplayer_fragment.xml +++ b/app/src/main/res/layout/audioplayer_fragment.xml @@ -136,8 +136,8 @@ castButtons = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,9 +59,10 @@ public abstract class CastEnabledActivity extends AppCompatActivity }; castManager = CastManager.getInstance(); castManager.addCastConsumer(castConsumer); - castButtonVisibilityManager = new CastButtonVisibilityManager(castManager); + CastButtonVisibilityManager castButtonVisibilityManager = new CastButtonVisibilityManager(castManager); castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled()); onCastConnectionChanged(castManager.isConnected()); + castButtons.add(castButtonVisibilityManager); } @Override @@ -75,47 +77,15 @@ public abstract class CastEnabledActivity extends AppCompatActivity super.onDestroy(); } - @Override - @CallSuper - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - if (!CastManager.isInitialized()) { - return true; - } - getMenuInflater().inflate(R.menu.cast_enabled, menu); - castButtonVisibilityManager.setMenu(menu); - return true; - } - - @Override - @CallSuper - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - if (!CastManager.isInitialized()) { - return true; - } - - MenuItem mediaRouteButton = menu.findItem(R.id.media_route_menu_item); - if (mediaRouteButton == null) { - Log.wtf(TAG, "MediaRoute item could not be found on the menu!", new Exception()); - mediaRouteActionProvider = null; - return true; - } - mediaRouteActionProvider = castManager.addMediaRouterButton(mediaRouteButton); - if (mediaRouteActionProvider != null) { - castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider; - mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable()); - } - return true; - } - @Override protected void onResume() { super.onResume(); if (!CastManager.isInitialized()) { return; } - castButtonVisibilityManager.setResumed(true); + for (CastButtonVisibilityManager castButton : castButtons) { + castButton.setResumed(true); + } } @Override @@ -124,7 +94,9 @@ public abstract class CastEnabledActivity extends AppCompatActivity if (!CastManager.isInitialized()) { return; } - castButtonVisibilityManager.setResumed(false); + for (CastButtonVisibilityManager castButton : castButtons) { + castButton.setResumed(false); + } } @@ -133,7 +105,9 @@ public abstract class CastEnabledActivity extends AppCompatActivity if (UserPreferences.PREF_CAST_ENABLED.equals(key)) { boolean newValue = UserPreferences.isCastEnabled(); Log.d(TAG, "onSharedPreferenceChanged(), isCastEnabled set to " + newValue); - castButtonVisibilityManager.setPrefEnabled(newValue); + for (CastButtonVisibilityManager castButton : castButtons) { + castButton.setPrefEnabled(newValue); + } // PlaybackService has its own listener, so if it's active we don't have to take action here. if (!newValue && !PlaybackService.isRunning) { CastManager.getInstance().disconnect(); @@ -143,135 +117,41 @@ public abstract class CastEnabledActivity extends AppCompatActivity private void onCastConnectionChanged(boolean connected) { if (connected) { - castButtonVisibilityManager.onConnected(); + for (CastButtonVisibilityManager castButton : castButtons) { + castButton.onConnected(); + } setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); } else { - castButtonVisibilityManager.onDisconnected(); + for (CastButtonVisibilityManager castButton : castButtons) { + castButton.onDisconnected(); + } setVolumeControlStream(AudioManager.STREAM_MUSIC); } } /** * Should be called by any activity or fragment for which the cast button should be shown. - * - * @param showAsAction refer to {@link MenuItem#setShowAsAction(int)} */ - public final void requestCastButton(int showAsAction) { + public final void requestCastButton(Menu menu) { if (!CastManager.isInitialized()) { return; } - castButtonVisibilityManager.requestCastButton(showAsAction); - } - - public static class CastButtonVisibilityManager { - private final CastManager castManager; - private volatile boolean prefEnabled = false; - private volatile boolean viewRequested = false; - private volatile boolean resumed = false; - private volatile boolean connected = false; - private volatile int showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM; - private Menu menu; - public SwitchableMediaRouteActionProvider mediaRouteActionProvider; - - public CastButtonVisibilityManager(CastManager castManager) { - this.castManager = castManager; - } - public synchronized void setPrefEnabled(boolean newValue) { - if (prefEnabled != newValue && resumed && (viewRequested || connected)) { - if (newValue) { - castManager.incrementUiCounter(); - } else { - castManager.decrementUiCounter(); - } - } - prefEnabled = newValue; - if (mediaRouteActionProvider != null) { - mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); - } - } - - public synchronized void setResumed(boolean newValue) { - if (resumed == newValue) { - Log.e(TAG, "resumed should never change to the same value"); - return; - } - resumed = newValue; - if (prefEnabled && (viewRequested || connected)) { - if (resumed) { - castManager.incrementUiCounter(); - } else { - castManager.decrementUiCounter(); - } - } - } - - public synchronized void setViewRequested(boolean newValue) { - if (viewRequested != newValue && resumed && prefEnabled && !connected) { - if (newValue) { - castManager.incrementUiCounter(); - } else { - castManager.decrementUiCounter(); - } - } - viewRequested = newValue; - if (mediaRouteActionProvider != null) { - mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); - } - } - - public synchronized void setConnected(boolean newValue) { - if (connected != newValue && resumed && prefEnabled && !prefEnabled) { - if (newValue) { - castManager.incrementUiCounter(); - } else { - castManager.decrementUiCounter(); - } - } - connected = newValue; - if (mediaRouteActionProvider != null) { - mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); - } - } - - public synchronized boolean shouldEnable() { - return prefEnabled && viewRequested; - } - - public void setMenu(Menu menu) { - setViewRequested(false); - showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM; - this.menu = menu; - setShowAsAction(); - } - - public void requestCastButton(int showAsAction) { - setViewRequested(true); - this.showAsAction = showAsAction; - setShowAsAction(); - } - - public void onConnected() { - setConnected(true); - setShowAsAction(); - } - - public void onDisconnected() { - setConnected(false); - setShowAsAction(); + MenuItem mediaRouteButton = menu.findItem(R.id.media_route_menu_item); + if (mediaRouteButton == null) { + getMenuInflater().inflate(R.menu.cast_enabled, menu); + mediaRouteButton = menu.findItem(R.id.media_route_menu_item); } - private void setShowAsAction() { - if (menu == null) { - Log.d(TAG, "setShowAsAction() without a menu"); - return; - } - MenuItem item = menu.findItem(R.id.media_route_menu_item); - if (item == null) { - Log.e(TAG, "setShowAsAction(), but cast button not inflated"); - return; - } - MenuItemCompat.setShowAsAction(item, connected? MenuItem.SHOW_AS_ACTION_ALWAYS : showAsAction); - } + SwitchableMediaRouteActionProvider mediaRouteActionProvider = + CastManager.getInstance().addMediaRouterButton(mediaRouteButton); + CastButtonVisibilityManager castButtonVisibilityManager = + new CastButtonVisibilityManager(CastManager.getInstance()); + castButtonVisibilityManager.setMenu(menu); + castButtonVisibilityManager.setPrefEnabled(UserPreferences.isCastEnabled()); + castButtonVisibilityManager.mediaRouteActionProvider = mediaRouteActionProvider; + castButtonVisibilityManager.setResumed(true); + castButtonVisibilityManager.requestCastButton(MenuItem.SHOW_AS_ACTION_ALWAYS); + mediaRouteActionProvider.setEnabled(castButtonVisibilityManager.shouldEnable()); } } diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastButtonVisibilityManager.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastButtonVisibilityManager.java new file mode 100644 index 000000000..527a652e3 --- /dev/null +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastButtonVisibilityManager.java @@ -0,0 +1,120 @@ +package de.danoeh.antennapod.core.cast; + +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import androidx.core.view.MenuItemCompat; +import de.danoeh.antennapod.core.R; + +public class CastButtonVisibilityManager { + private static final String TAG = "CastBtnVisibilityMgr"; + private final CastManager castManager; + private volatile boolean prefEnabled = false; + private volatile boolean viewRequested = false; + private volatile boolean resumed = false; + private volatile boolean connected = false; + private volatile int showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM; + private Menu menu; + public SwitchableMediaRouteActionProvider mediaRouteActionProvider; + + public CastButtonVisibilityManager(CastManager castManager) { + this.castManager = castManager; + } + + public synchronized void setPrefEnabled(boolean newValue) { + if (prefEnabled != newValue && resumed && (viewRequested || connected)) { + if (newValue) { + castManager.incrementUiCounter(); + } else { + castManager.decrementUiCounter(); + } + } + prefEnabled = newValue; + if (mediaRouteActionProvider != null) { + mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); + } + } + + public synchronized void setResumed(boolean newValue) { + if (resumed == newValue) { + Log.e(TAG, "resumed should never change to the same value"); + return; + } + resumed = newValue; + if (prefEnabled && (viewRequested || connected)) { + if (resumed) { + castManager.incrementUiCounter(); + } else { + castManager.decrementUiCounter(); + } + } + } + + public synchronized void setViewRequested(boolean newValue) { + if (viewRequested != newValue && resumed && prefEnabled && !connected) { + if (newValue) { + castManager.incrementUiCounter(); + } else { + castManager.decrementUiCounter(); + } + } + viewRequested = newValue; + if (mediaRouteActionProvider != null) { + mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); + } + } + + public synchronized void setConnected(boolean newValue) { + if (connected != newValue && resumed && prefEnabled && !prefEnabled) { + if (newValue) { + castManager.incrementUiCounter(); + } else { + castManager.decrementUiCounter(); + } + } + connected = newValue; + if (mediaRouteActionProvider != null) { + mediaRouteActionProvider.setEnabled(prefEnabled && (viewRequested || connected)); + } + } + + public synchronized boolean shouldEnable() { + return prefEnabled && viewRequested; + } + + public void setMenu(Menu menu) { + setViewRequested(false); + showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM; + this.menu = menu; + setShowAsAction(); + } + + public void requestCastButton(int showAsAction) { + setViewRequested(true); + this.showAsAction = showAsAction; + setShowAsAction(); + } + + public void onConnected() { + setConnected(true); + setShowAsAction(); + } + + public void onDisconnected() { + setConnected(false); + setShowAsAction(); + } + + private void setShowAsAction() { + if (menu == null) { + Log.d(TAG, "setShowAsAction() without a menu"); + return; + } + MenuItem item = menu.findItem(R.id.media_route_menu_item); + if (item == null) { + Log.e(TAG, "setShowAsAction(), but cast button not inflated"); + return; + } + MenuItemCompat.setShowAsAction(item, connected ? MenuItem.SHOW_AS_ACTION_ALWAYS : showAsAction); + } +} -- cgit v1.2.3 From 0a7d054aad0a0f48505c1ea10f2b0aeea9e10675 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 17:09:03 +0100 Subject: Removed AudioPlayerActivity --- app/src/main/AndroidManifest.xml | 17 --- .../antennapod/activity/AudioplayerActivity.java | 136 --------------------- .../antennapod/activity/CastplayerActivity.java | 18 +-- .../danoeh/antennapod/activity/MainActivity.java | 7 +- .../antennapod/activity/VideoplayerActivity.java | 7 +- .../config/PlaybackServiceCallbacksImpl.java | 4 +- 6 files changed, 10 insertions(+), 179 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 62335b5e6..ec36cf49b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,23 +73,6 @@ android:label="@string/app_name"> - - - - - - - - - - - - - diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java deleted file mode 100644 index ae8634516..000000000 --- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ /dev/null @@ -1,136 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.content.Intent; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import de.danoeh.antennapod.core.feed.MediaType; -import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; -import de.danoeh.antennapod.core.preferences.PlaybackPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.dialog.VariableSpeedDialog; - -import java.text.DecimalFormat; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Activity for playing audio files. - */ -public class AudioplayerActivity extends MediaplayerInfoActivity { - private static final String TAG = "AudioPlayerActivity"; - private static final float EPSILON = 0.001f; - - private final AtomicBoolean isSetup = new AtomicBoolean(false); - - @Override - protected void onResume() { - super.onResume(); - if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { - playExternalMedia(getIntent(), MediaType.AUDIO); - } else if (PlaybackService.isCasting()) { - Intent intent = PlaybackService.getPlayerActivityIntent(this); - if (intent.getComponent() != null - && !intent.getComponent().getClassName().equals(AudioplayerActivity.class.getName())) { - saveCurrentFragment(); - finish(); - startActivity(intent); - } - } - } - - @Override - protected void onReloadNotification(int notificationCode) { - if (notificationCode == PlaybackService.EXTRA_CODE_CAST) { - Log.d(TAG, "ReloadNotification received, switching to Castplayer now"); - saveCurrentFragment(); - finish(); - startActivity(new Intent(this, CastplayerActivity.class)); - - } else { - super.onReloadNotification(notificationCode); - } - } - - @Override - protected void updatePlaybackSpeedButton() { - if (butPlaybackSpeed == null) { - return; - } - if (controller == null) { - butPlaybackSpeed.setVisibility(View.GONE); - txtvPlaybackSpeed.setVisibility(View.GONE); - return; - } - updatePlaybackSpeedButtonText(); - butPlaybackSpeed.setAlpha(controller.canSetPlaybackSpeed() ? 1.0f : 0.5f); - butPlaybackSpeed.setVisibility(View.VISIBLE); - txtvPlaybackSpeed.setVisibility(View.VISIBLE); - } - - @Override - protected void updatePlaybackSpeedButtonText() { - if (butPlaybackSpeed == null) { - return; - } - if (controller == null) { - butPlaybackSpeed.setVisibility(View.GONE); - txtvPlaybackSpeed.setVisibility(View.GONE); - return; - } - float speed = 1.0f; - if (controller.canSetPlaybackSpeed()) { - speed = PlaybackSpeedUtils.getCurrentPlaybackSpeed(controller.getMedia()); - } - String speedStr = new DecimalFormat("0.00").format(speed); - txtvPlaybackSpeed.setText(speedStr); - butPlaybackSpeed.setSpeed(speed); - } - - @Override - protected void setupGUI() { - if (isSetup.getAndSet(true)) { - return; - } - super.setupGUI(); - if (butPlaybackSpeed != null) { - butPlaybackSpeed.setOnClickListener(v -> { - if (controller == null) { - return; - } - if (controller.canSetPlaybackSpeed()) { - float[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); - float currentSpeed = controller.getCurrentPlaybackSpeedMultiplier(); - - int newSpeedIndex = 0; - while (newSpeedIndex < availableSpeeds.length - && availableSpeeds[newSpeedIndex] < currentSpeed + EPSILON) { - newSpeedIndex++; - } - - float newSpeed; - if (availableSpeeds.length == 0) { - newSpeed = 1.0f; - } else if (newSpeedIndex == availableSpeeds.length) { - newSpeed = availableSpeeds[0]; - } else { - newSpeed = availableSpeeds[newSpeedIndex]; - } - - PlaybackPreferences.setCurrentlyPlayingTemporaryPlaybackSpeed(newSpeed); - UserPreferences.setPlaybackSpeed(newSpeed); - controller.setPlaybackSpeed(newSpeed); - onPositionObserverUpdate(); - } else { - VariableSpeedDialog.showGetPluginDialog(this); - } - }); - butPlaybackSpeed.setOnLongClickListener(v -> { - VariableSpeedDialog.showDialog(this); - return true; - }); - butPlaybackSpeed.setVisibility(View.VISIBLE); - txtvPlaybackSpeed.setVisibility(View.VISIBLE); - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java index bbab235c8..bf4e64881 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java @@ -2,13 +2,11 @@ package de.danoeh.antennapod.activity; import android.content.Intent; import android.os.Bundle; -import android.util.Log; import android.view.View; +import de.danoeh.antennapod.core.service.playback.PlaybackService; import java.util.concurrent.atomic.AtomicBoolean; -import de.danoeh.antennapod.core.service.playback.PlaybackService; - /** * Activity for controlling the remote playback on a Cast device. */ @@ -29,21 +27,9 @@ public class CastplayerActivity extends MediaplayerInfoActivity { } } - @Override - protected void onReloadNotification(int notificationCode) { - if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) { - Log.d(TAG, "ReloadNotification received, switching to Audioplayer now"); - saveCurrentFragment(); - finish(); - startActivity(new Intent(this, AudioplayerActivity.class)); - } else { - super.onReloadNotification(notificationCode); - } - } - @Override protected void setupGUI() { - if(isSetup.getAndSet(true)) { + if (isSetup.getAndSet(true)) { return; } super.setupGUI(); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 115114504..ed3ae7637 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -63,6 +63,7 @@ public class MainActivity extends CastEnabledActivity { public static final String EXTRA_FRAGMENT_TAG = "fragment_tag"; public static final String EXTRA_FRAGMENT_ARGS = "fragment_args"; public static final String EXTRA_FEED_ID = "fragment_feed_id"; + public static final String EXTRA_OPEN_PLAYER = "open_player"; private static final String SAVE_BACKSTACK_COUNT = "backstackCount"; @@ -403,9 +404,11 @@ public class MainActivity extends CastEnabledActivity { } else if (feedId > 0) { loadFeedFragmentById(feedId, args); } - // to avoid handling the intent twice when the configuration changes - setIntent(new Intent(MainActivity.this, MainActivity.class)); + } else if (intent.hasExtra(EXTRA_OPEN_PLAYER)) { + sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); } + // to avoid handling the intent twice when the configuration changes + setIntent(new Intent(MainActivity.this, MainActivity.class)); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index b8a30f994..a9b07b629 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -278,12 +278,7 @@ public class VideoplayerActivity extends MediaplayerActivity { } return; } - if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) { - Log.d(TAG, "ReloadNotification received, switching to Audioplayer now"); - destroyingDueToReload = true; - finish(); - startActivity(new Intent(this, AudioplayerActivity.class)); - } else if (notificationCode == PlaybackService.EXTRA_CODE_CAST) { + if (notificationCode == PlaybackService.EXTRA_CODE_CAST) { Log.d(TAG, "ReloadNotification received, switching to Castplayer now"); destroyingDueToReload = true; finish(); diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java index c3f5d898c..98b5f4b2b 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java @@ -4,8 +4,8 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.AudioplayerActivity; import de.danoeh.antennapod.activity.CastplayerActivity; +import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.VideoplayerActivity; import de.danoeh.antennapod.core.PlaybackServiceCallbacks; import de.danoeh.antennapod.core.feed.MediaType; @@ -24,7 +24,7 @@ public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks { } return i; } else { - return new Intent(context, AudioplayerActivity.class); + return new Intent(context, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true); } } -- cgit v1.2.3 From cbb310080eb468dc6789a7952f36cd2e1816e8b1 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 17:49:25 +0100 Subject: Redesign ExternalPlayerFragment --- .../bottomsheet/ViewPagerBottomSheetBehavior.java | 4 +- .../fragment/ExternalPlayerFragment.java | 27 ++-- app/src/main/res/drawable/shadow.xml | 7 - .../main/res/layout/external_player_fragment.xml | 157 ++++++++++----------- core/src/main/res/values/dimens.xml | 2 +- 5 files changed, 97 insertions(+), 100 deletions(-) delete mode 100644 app/src/main/res/drawable/shadow.xml diff --git a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java index 1e76b3bc1..1667006a5 100644 --- a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java +++ b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java @@ -34,7 +34,9 @@ public class ViewPagerBottomSheetBehavior extends BottomSheetBeh if (view instanceof ViewPager) { ViewPager viewPager = (ViewPager) view; View currentViewPagerChild = viewPager.getChildAt(viewPager.getCurrentItem()); - return findScrollingChild(currentViewPagerChild); + if (currentViewPagerChild != null) { + return findScrollingChild(currentViewPagerChild); + } } else if (view instanceof ViewGroup) { ViewGroup group = (ViewGroup) view; for (int i = 0, count = group.getChildCount(); i < count; i++) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index 57193e08b..03b1d6f8f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -40,7 +40,6 @@ import org.greenrobot.eventbus.ThreadMode; public class ExternalPlayerFragment extends Fragment { public static final String TAG = "ExternalPlayerFragment"; - private ViewGroup fragmentLayout; private ImageView imgvCover; private TextView txtvTitle; private ImageButton butPlay; @@ -56,16 +55,14 @@ public class ExternalPlayerFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View root = inflater.inflate(R.layout.external_player_fragment, - container, false); - fragmentLayout = root.findViewById(R.id.fragmentLayout); + View root = inflater.inflate(R.layout.external_player_fragment, container, false); imgvCover = root.findViewById(R.id.imgvCover); txtvTitle = root.findViewById(R.id.txtvTitle); butPlay = root.findViewById(R.id.butPlay); mFeedName = root.findViewById(R.id.txtvAuthor); mProgressBar = root.findViewById(R.id.episodeProgress); - fragmentLayout.setOnClickListener(v -> { + root.findViewById(R.id.fragmentLayout).setOnClickListener(v -> { Log.d(TAG, "layoutInfo was clicked"); if (controller != null && controller.getMedia() != null) { @@ -175,9 +172,7 @@ public class ExternalPlayerFragment extends Fragment { } private void playbackDone() { - if (fragmentLayout != null) { - fragmentLayout.setVisibility(View.GONE); - } + clearUi(); if (controller != null) { controller.release(); } @@ -214,10 +209,22 @@ public class ExternalPlayerFragment extends Fragment { .observeOn(AndroidSchedulers.mainThread()) .subscribe(media -> updateUi((Playable) media), error -> Log.e(TAG, Log.getStackTraceString(error)), - () -> fragmentLayout.setVisibility(View.GONE)); + this::clearUi); return true; } + private void clearUi() { + if (txtvTitle == null || mFeedName == null || mProgressBar == null || butPlay == null) { + return; + } + txtvTitle.setText(R.string.no_media_playing_label); + mFeedName.setText(""); + butPlay.setVisibility(View.GONE); + mProgressBar.setProgress(0); + Glide.with(getActivity()).clear(imgvCover); + ((MainActivity) getActivity()).getBottomSheet().setLocked(true); + } + private void updateUi(Playable media) { if (media != null) { txtvTitle.setText(media.getEpisodeTitle()); @@ -233,8 +240,6 @@ public class ExternalPlayerFragment extends Fragment { .fitCenter() .dontAnimate()) .into(imgvCover); - - fragmentLayout.setVisibility(View.VISIBLE); if (controller != null && controller.isPlayingVideoLocally()) { butPlay.setVisibility(View.GONE); ((MainActivity) getActivity()).getBottomSheet().setLocked(true); diff --git a/app/src/main/res/drawable/shadow.xml b/app/src/main/res/drawable/shadow.xml deleted file mode 100644 index fc5110e0b..000000000 --- a/app/src/main/res/drawable/shadow.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/layout/external_player_fragment.xml b/app/src/main/res/layout/external_player_fragment.xml index 3e2efe47e..651953b0e 100644 --- a/app/src/main/res/layout/external_player_fragment.xml +++ b/app/src/main/res/layout/external_player_fragment.xml @@ -1,87 +1,84 @@ - - - + android:background="?attr/selectableItemBackground" + android:orientation="vertical"> - + - + + + - - + + + + + + + + + + + + + - + diff --git a/core/src/main/res/values/dimens.xml b/core/src/main/res/values/dimens.xml index 5083eb749..cfb272ad9 100644 --- a/core/src/main/res/values/dimens.xml +++ b/core/src/main/res/values/dimens.xml @@ -3,7 +3,7 @@ 0dp 70dp - 56dp + 64dp 20dp 12sp 14sp -- cgit v1.2.3 From 4ee04b3409e4b31142e8b9fb82ad6018f63756b7 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 18:18:14 +0100 Subject: Updated tests --- .../de/test/antennapod/ui/SpeedChangeTest.java | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java index 194d51a3c..5565bf474 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java @@ -7,12 +7,14 @@ import android.preference.PreferenceManager; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.AudioplayerActivity; +import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.fragment.ExternalPlayerFragment; import de.danoeh.antennapod.fragment.QueueFragment; import de.test.antennapod.EspressoTestUtils; import de.test.antennapod.IgnoreOnCi; @@ -34,6 +36,8 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static de.test.antennapod.EspressoTestUtils.waitForView; +import static de.test.antennapod.NthMatcher.first; +import static org.hamcrest.Matchers.allOf; /** * User interface tests for changing the playback speed. @@ -43,10 +47,10 @@ import static de.test.antennapod.EspressoTestUtils.waitForView; public class SpeedChangeTest { @Rule - public ActivityTestRule activityRule - = new ActivityTestRule<>(AudioplayerActivity.class, false, false); + public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class, false, false); private UITestUtils uiTestUtils; private String[] availableSpeeds; + private PlaybackController controller; @Before public void setUp() throws Exception { @@ -70,7 +74,10 @@ public class SpeedChangeTest { UserPreferences.setPlaybackSpeedArray(availableSpeeds); EspressoTestUtils.tryKillPlaybackService(); - activityRule.launchActivity(new Intent()); + activityRule.launchActivity(new Intent().putExtra(MainActivity.EXTRA_OPEN_PLAYER, true)); + controller = new PlaybackController(activityRule.getActivity(), true); + controller.init(); + controller.getMedia(); // To load media } @After @@ -86,21 +93,21 @@ public class SpeedChangeTest { @Test public void testChangeSpeedPlaying() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); - onView(withId(R.id.butPlay)).perform(click()); + controller.playPause(); Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() - -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); + -> controller.getStatus() == PlayerStatus.PLAYING); clickThroughSpeeds(); } @Test public void testChangeSpeedPaused() { onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000)); - onView(withId(R.id.butPlay)).perform(click()); + controller.playPause(); Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() - -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING); - onView(withId(R.id.butPlay)).perform(click()); + -> controller.getStatus() == PlayerStatus.PLAYING); + controller.playPause(); Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() - -> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PAUSED); + -> controller.getStatus() == PlayerStatus.PAUSED); clickThroughSpeeds(); } -- cgit v1.2.3 From 44df74fc170f4e49b415d7369c679816042ffb5a Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 21:21:15 +0100 Subject: Removed CastPlayerActivity --- app/src/main/AndroidManifest.xml | 8 - .../antennapod/activity/CastplayerActivity.java | 66 ------ .../activity/MediaplayerInfoActivity.java | 254 --------------------- .../antennapod/activity/VideoplayerActivity.java | 2 +- .../config/PlaybackServiceCallbacksImpl.java | 11 +- 5 files changed, 4 insertions(+), 337 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ec36cf49b..3f0df81f1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,14 +73,6 @@ android:label="@string/app_name"> - - - - diff --git a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java deleted file mode 100644 index bf4e64881..000000000 --- a/app/src/main/java/de/danoeh/antennapod/activity/CastplayerActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import de.danoeh.antennapod.core.service.playback.PlaybackService; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Activity for controlling the remote playback on a Cast device. - */ -public class CastplayerActivity extends MediaplayerInfoActivity { - private static final String TAG = "CastPlayerActivity"; - - private final AtomicBoolean isSetup = new AtomicBoolean(false); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (!PlaybackService.isCasting()) { - Intent intent = PlaybackService.getPlayerActivityIntent(this); - if (!intent.getComponent().getClassName().equals(CastplayerActivity.class.getName())) { - finish(); - startActivity(intent); - } - } - } - - @Override - protected void setupGUI() { - if (isSetup.getAndSet(true)) { - return; - } - super.setupGUI(); - if (butPlaybackSpeed != null) { - butPlaybackSpeed.setVisibility(View.GONE); - txtvPlaybackSpeed.setVisibility(View.GONE); - } - } - - @Override - protected void onResume() { - if (!PlaybackService.isCasting()) { - Intent intent = PlaybackService.getPlayerActivityIntent(this); - if (!intent.getComponent().getClassName().equals(CastplayerActivity.class.getName())) { - saveCurrentFragment(); - finish(); - startActivity(intent); - } - } - super.onResume(); - } - - @Override - protected void onBufferStart() { - //sbPosition.setIndeterminate(true); - sbPosition.setEnabled(false); - } - - @Override - protected void onBufferEnd() { - //sbPosition.setIndeterminate(false); - sbPosition.setEnabled(true); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java deleted file mode 100644 index 7e4ccbe23..000000000 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerInfoActivity.java +++ /dev/null @@ -1,254 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.os.Bundle; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.widget.Toolbar; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.viewpager.widget.ViewPager; -import com.google.android.material.snackbar.Snackbar; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.event.MessageEvent; -import de.danoeh.antennapod.core.feed.Chapter; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.util.playback.PlaybackController; -import de.danoeh.antennapod.fragment.ChaptersFragment; -import de.danoeh.antennapod.fragment.CoverFragment; -import de.danoeh.antennapod.fragment.ItemDescriptionFragment; -import de.danoeh.antennapod.fragment.NavDrawerFragment; -import de.danoeh.antennapod.view.PagerIndicatorView; -import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.List; - -/** - * Activity for playing files that do not require a video surface. - */ -public abstract class MediaplayerInfoActivity extends MediaplayerActivity { - - private static final String TAG = "MediaplayerInfoActivity"; - - private static final int POS_COVER = 0; - private static final int POS_DESCR = 1; - private static final int POS_CHAPTERS = 2; - private static final int NUM_CONTENT_FRAGMENTS = 3; - - private static final String PREFS = "AudioPlayerActivityPreferences"; - private static final String PREF_KEY_SELECTED_FRAGMENT_POSITION = "selectedFragmentPosition"; - - PlaybackSpeedIndicatorView butPlaybackSpeed; - TextView txtvPlaybackSpeed; - private DrawerLayout drawerLayout; - private View navDrawer; - private ActionBarDrawerToggle drawerToggle; - private ViewPager pager; - private PagerIndicatorView pageIndicator; - private MediaplayerInfoPagerAdapter pagerAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - supportPostponeEnterTransition(); - } - - @Override - protected void onStop() { - super.onStop(); - Log.d(TAG, "onStop()"); - saveCurrentFragment(); - } - - @Override - public void onDestroy() { - Log.d(TAG, "onDestroy()"); - super.onDestroy(); - // don't risk creating memory leaks - drawerLayout = null; - navDrawer = null; - drawerToggle = null; - pager = null; - pagerAdapter = null; - } - - @Override - protected void chooseTheme() { - setTheme(UserPreferences.getNoTitleTheme()); - } - - void saveCurrentFragment() { - if (pager == null) { - return; - } - Log.d(TAG, "Saving preferences"); - SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); - prefs.edit() - .putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem()) - .apply(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (drawerToggle != null) { - drawerToggle.onConfigurationChanged(newConfig); - } - } - - private void loadLastFragment() { - Log.d(TAG, "Restoring instance state"); - SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); - int lastPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1); - pager.setCurrentItem(lastPosition); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); - } - - @Override - protected void onAwaitingVideoSurface() { - Log.d(TAG, "onAwaitingVideoSurface was called in audio player -> switching to video player"); - startActivity(new Intent(this, VideoplayerActivity.class)); - } - - @Override - protected void setupGUI() { - super.setupGUI(); - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setTitle(""); - drawerLayout = findViewById(R.id.drawer_layout); - navDrawer = findViewById(R.id.navDrawerFragment); - butPlaybackSpeed = findViewById(R.id.butPlaybackSpeed); - txtvPlaybackSpeed = findViewById(R.id.txtvPlaybackSpeed); - - drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); - drawerToggle.setDrawerIndicatorEnabled(false); - drawerLayout.addDrawerListener(drawerToggle); - drawerToggle.syncState(); - - getSupportFragmentManager().beginTransaction() - .replace(R.id.navDrawerFragment, new NavDrawerFragment(), NavDrawerFragment.TAG) - .commit(); - - pager = findViewById(R.id.pager); - pager.setOffscreenPageLimit(3); - pagerAdapter = new MediaplayerInfoPagerAdapter(getSupportFragmentManager()); - pager.setAdapter(pagerAdapter); - pageIndicator = findViewById(R.id.page_indicator); - pageIndicator.setViewPager(pager); - pageIndicator.setOnClickListener(v - -> pager.setCurrentItem((pager.getCurrentItem() + 1) % pager.getChildCount())); - loadLastFragment(); - pager.onSaveInstanceState(); - - pager.post(this::supportStartPostponedEnterTransition); - } - - @Override - boolean loadMediaInfo() { - if (controller != null && controller.getMedia() != null) { - List chapters = controller.getMedia().getChapters(); - boolean hasChapters = chapters != null && !chapters.isEmpty(); - pageIndicator.setDisabledPage(hasChapters ? -1 : 2); - } - return super.loadMediaInfo(); - } - - @Override - protected void onReloadNotification(int notificationCode) { - if (notificationCode == PlaybackService.EXTRA_CODE_VIDEO) { - Log.d(TAG, "ReloadNotification received, switching to Videoplayer now"); - finish(); - startActivity(new Intent(this, VideoplayerActivity.class)); - - } - } - - public PlaybackController getPlaybackController() { - return controller; - } - - public boolean isDrawerOpen() { - return drawerLayout != null && navDrawer != null && drawerLayout.isDrawerOpen(navDrawer); - } - - @Override - protected int getContentViewResourceId() { - return R.layout.mediaplayerinfo_activity; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) || super.onOptionsItemSelected(item); - } - - @Override - public void onBackPressed() { - if (isDrawerOpen()) { - drawerLayout.closeDrawer(navDrawer); - } else if (pager == null || pager.getCurrentItem() == 0) { - // If the user is currently looking at the first step, allow the system to handle the - // Back button. This calls finish() on this activity and pops the back stack. - super.onBackPressed(); - } else { - // Otherwise, select the previous step. - pager.setCurrentItem(pager.getCurrentItem() - 1); - } - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onEventMainThread(MessageEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); - View parentLayout = findViewById(R.id.drawer_layout); - Snackbar snackbar = Snackbar.make(parentLayout, event.message, Snackbar.LENGTH_SHORT); - if (event.action != null) { - snackbar.setAction(getString(R.string.undo), v -> event.action.run()); - } - snackbar.show(); - } - - private static class MediaplayerInfoPagerAdapter extends FragmentStatePagerAdapter { - private static final String TAG = "MPInfoPagerAdapter"; - - public MediaplayerInfoPagerAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - Log.d(TAG, "getItem(" + position + ")"); - switch (position) { - case POS_COVER: - return new CoverFragment(); - case POS_DESCR: - return new ItemDescriptionFragment(); - case POS_CHAPTERS: - return new ChaptersFragment(); - default: - return null; - } - } - - @Override - public int getCount() { - return NUM_CONTENT_FRAGMENTS; - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index a9b07b629..212cb2f75 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -282,7 +282,7 @@ public class VideoplayerActivity extends MediaplayerActivity { Log.d(TAG, "ReloadNotification received, switching to Castplayer now"); destroyingDueToReload = true; finish(); - startActivity(new Intent(this, CastplayerActivity.class)); + startActivity(new Intent(this, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true)); } } diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java index 98b5f4b2b..09f1af7d7 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java @@ -4,27 +4,22 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.CastplayerActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.VideoplayerActivity; import de.danoeh.antennapod.core.PlaybackServiceCallbacks; import de.danoeh.antennapod.core.feed.MediaType; - public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks { @Override public Intent getPlayerActivityIntent(Context context, MediaType mediaType, boolean remotePlayback) { - if (remotePlayback) { - return new Intent(context, CastplayerActivity.class); - } - if (mediaType == MediaType.VIDEO) { + if (mediaType == MediaType.AUDIO || remotePlayback) { + return new Intent(context, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true); + } else { Intent i = new Intent(context, VideoplayerActivity.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { i.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); } return i; - } else { - return new Intent(context, MainActivity.class).putExtra(MainActivity.EXTRA_OPEN_PLAYER, true); } } -- cgit v1.2.3 From a4c4d116deb43a4b89940c7b849aee6309ccf1f5 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 21:34:05 +0100 Subject: Fixed crash Not sure why that crash appeared now... --- .../de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java | 4 ++-- .../main/java/de/danoeh/antennapod/fragment/QueueFragment.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java index 9514ea5eb..40b8d5b84 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java @@ -313,7 +313,7 @@ public class EpisodesApplyActionFragment extends Fragment { } } if (resId != 0) { - Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT) + Snackbar.make(getActivity().findViewById(android.R.id.content), resId, Snackbar.LENGTH_SHORT) .show(); return true; } else { @@ -469,7 +469,7 @@ public class EpisodesApplyActionFragment extends Fragment { private void close(@PluralsRes int msgId, int numItems) { if (numItems > 0) { - Snackbar.make(getActivity().findViewById(R.id.content), + Snackbar.make(getActivity().findViewById(android.R.id.content), getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG ) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 0a752b855..0411fd01b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -416,11 +416,11 @@ public class QueueFragment extends Fragment { recyclerAdapter.setLocked(locked); } if (locked) { - Snackbar.make(getActivity().findViewById(R.id.content), R.string - .queue_locked, Snackbar.LENGTH_SHORT).show(); + Snackbar.make(getActivity().findViewById(android.R.id.content), + R.string.queue_locked, Snackbar.LENGTH_SHORT).show(); } else { - Snackbar.make(getActivity().findViewById(R.id.content), R.string - .queue_unlocked, Snackbar.LENGTH_SHORT).show(); + Snackbar.make(getActivity().findViewById(android.R.id.content), + R.string.queue_unlocked, Snackbar.LENGTH_SHORT).show(); } } -- cgit v1.2.3 From d87cc27c9bdfd7fa68df6e09bf184bd75393212b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 25 Mar 2020 21:45:58 +0100 Subject: Deleted unused layout file --- .../main/res/layout/mediaplayerinfo_activity.xml | 248 --------------------- 1 file changed, 248 deletions(-) delete mode 100644 app/src/main/res/layout/mediaplayerinfo_activity.xml diff --git a/app/src/main/res/layout/mediaplayerinfo_activity.xml b/app/src/main/res/layout/mediaplayerinfo_activity.xml deleted file mode 100644 index 526994752..000000000 --- a/app/src/main/res/layout/mediaplayerinfo_activity.xml +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file -- cgit v1.2.3