Add scrubbing time overlay (#4786)

This commit is contained in:
asdoi 2021-01-21 18:37:04 +01:00 committed by GitHub
parent 86bf6a50f3
commit 2a8abb02f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 106 additions and 20 deletions

View File

@ -1,6 +1,5 @@
package de.danoeh.antennapod.activity; package de.danoeh.antennapod.activity;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -28,7 +27,10 @@ import java.text.NumberFormat;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.core.app.ActivityOptionsCompat; import androidx.core.app.ActivityOptionsCompat;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
@ -56,7 +58,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
/** /**
* Provides general features which are both needed for playing audio and video * Provides general features which are both needed for playing audio and video
* files. * files.
@ -77,6 +78,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
private ImageButton butFF; private ImageButton butFF;
private TextView txtvFF; private TextView txtvFF;
private ImageButton butSkip; private ImageButton butSkip;
private CardView cardViewSeek;
private TextView txtvSeek;
private boolean showTimeLeft = false; private boolean showTimeLeft = false;
@ -482,6 +485,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
setContentView(getContentViewResourceId()); setContentView(getContentViewResourceId());
sbPosition = findViewById(R.id.sbPosition); sbPosition = findViewById(R.id.sbPosition);
txtvPosition = findViewById(R.id.txtvPosition); txtvPosition = findViewById(R.id.txtvPosition);
cardViewSeek = findViewById(R.id.cardViewSeek);
txtvSeek = findViewById(R.id.txtvSeek);
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false);
@ -608,21 +613,21 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
} }
if (fromUser) { if (fromUser) {
prog = progress / ((float) seekBar.getMax()); prog = progress / ((float) seekBar.getMax());
int duration = controller.getDuration();
TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
int position = converter.convert((int) (prog * duration)); int position = converter.convert((int) (prog * controller.getDuration()));
txtvPosition.setText(Converter.getDurationStringLong(position)); txtvSeek.setText(Converter.getDurationStringLong(position));
if (showTimeLeft) {
int timeLeft = converter.convert(duration - (int) (prog * duration));
txtvLength.setText("-" + Converter.getDurationStringLong(timeLeft));
}
} }
} }
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
cardViewSeek.setScaleX(.8f);
cardViewSeek.setScaleY(.8f);
cardViewSeek.animate()
.setInterpolator(new FastOutSlowInInterpolator())
.alpha(1f).scaleX(1f).scaleY(1f)
.setDuration(200)
.start();
} }
@Override @Override
@ -630,6 +635,13 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
if (controller != null) { if (controller != null) {
controller.seekTo((int) (prog * controller.getDuration())); controller.seekTo((int) (prog * controller.getDuration()));
} }
cardViewSeek.setScaleX(1f);
cardViewSeek.setScaleY(1f);
cardViewSeek.animate()
.setInterpolator(new FastOutSlowInInterpolator())
.alpha(0f).scaleX(.8f).scaleY(.8f)
.setDuration(200)
.start();
} }
private void checkFavorite() { private void checkFavorite() {

View File

@ -17,7 +17,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2; import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
@ -86,6 +88,8 @@ public class AudioPlayerFragment extends Fragment implements
private ImageButton butSkip; private ImageButton butSkip;
private Toolbar toolbar; private Toolbar toolbar;
private ProgressBar progressIndicator; private ProgressBar progressIndicator;
private CardView cardViewSeek;
private TextView txtvSeek;
private PlaybackController controller; private PlaybackController controller;
private Disposable disposable; private Disposable disposable;
@ -122,6 +126,8 @@ public class AudioPlayerFragment extends Fragment implements
txtvFF = root.findViewById(R.id.txtvFF); txtvFF = root.findViewById(R.id.txtvFF);
butSkip = root.findViewById(R.id.butSkip); butSkip = root.findViewById(R.id.butSkip);
progressIndicator = root.findViewById(R.id.progLoading); progressIndicator = root.findViewById(R.id.progLoading);
cardViewSeek = root.findViewById(R.id.cardViewSeek);
txtvSeek = root.findViewById(R.id.txtvSeek);
setupLengthTextView(); setupLengthTextView();
setupControlButtons(); setupControlButtons();
@ -454,22 +460,22 @@ public class AudioPlayerFragment extends Fragment implements
} }
if (fromUser) { if (fromUser) {
float prog = progress / ((float) seekBar.getMax()); float prog = progress / ((float) seekBar.getMax());
int duration = controller.getDuration();
TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
int position = converter.convert((int) (prog * duration)); int position = converter.convert((int) (prog * controller.getDuration()));
txtvPosition.setText(Converter.getDurationStringLong(position)); txtvSeek.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 @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
// interrupt position Observer, restart later // interrupt position Observer, restart later
cardViewSeek.setScaleX(.8f);
cardViewSeek.setScaleY(.8f);
cardViewSeek.animate()
.setInterpolator(new FastOutSlowInInterpolator())
.alpha(1f).scaleX(1f).scaleY(1f)
.setDuration(200)
.start();
} }
@Override @Override
@ -478,6 +484,13 @@ public class AudioPlayerFragment extends Fragment implements
float prog = seekBar.getProgress() / ((float) seekBar.getMax()); float prog = seekBar.getProgress() / ((float) seekBar.getMax());
controller.seekTo((int) (prog * controller.getDuration())); controller.seekTo((int) (prog * controller.getDuration()));
} }
cardViewSeek.setScaleX(1f);
cardViewSeek.setScaleY(1f);
cardViewSeek.animate()
.setInterpolator(new FastOutSlowInInterpolator())
.alpha(0f).scaleX(.8f).scaleY(.8f)
.setDuration(200)
.start();
} }
public void setupOptionsMenu(Playable media) { public void setupOptionsMenu(Playable media) {

View File

@ -51,6 +51,34 @@
app:tint="?android:attr/windowBackground" app:tint="?android:attr/windowBackground"
android:importantForAccessibility="no"/> android:importantForAccessibility="no"/>
<androidx.cardview.widget.CardView
android:id="@+id/cardViewSeek"
android:alpha="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/pager"
android:layout_centerHorizontal="true"
android:layout_marginBottom="12dp"
app:cardCornerRadius="8dp"
app:cardBackgroundColor="?attr/seek_background"
app:cardElevation="0dp"
tools:alpha="1">
<TextView
android:id="@+id/txtvSeek"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="24dp"
android:paddingTop="4dp"
android:paddingRight="24dp"
android:paddingBottom="4dp"
android:textColor="@color/white"
android:textSize="24sp"
tools:text="1:06:29" />
</androidx.cardview.widget.CardView>
<LinearLayout <LinearLayout
android:id="@+id/playtime_layout" android:id="@+id/playtime_layout"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/black" android:background="@color/black"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/videoframe"> android:id="@+id/videoframe">
@ -75,6 +76,33 @@
android:layout_gravity="bottom|center" android:layout_gravity="bottom|center"
android:orientation="vertical"> android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="@+id/cardViewSeek"
android:alpha="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_gravity="center"
app:cardCornerRadius="8dp"
app:cardBackgroundColor="?attr/seek_background"
app:cardElevation="0dp"
tools:alpha="1">
<TextView
android:id="@+id/txtvSeek"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="24dp"
android:paddingTop="4dp"
android:paddingRight="24dp"
android:paddingBottom="4dp"
android:textColor="@color/white"
android:textSize="24sp"
tools:text="1:06:29" />
</androidx.cardview.widget.CardView>
<RelativeLayout <RelativeLayout
android:id="@+id/timecontrol" android:id="@+id/timecontrol"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -62,6 +62,7 @@
<attr name="filter_dialog_clear" format="color"/> <attr name="filter_dialog_clear" format="color"/>
<attr name="filter_dialog_button_background" format="reference"/> <attr name="filter_dialog_button_background" format="reference"/>
<attr name="ic_notifications" format="reference"/> <attr name="ic_notifications" format="reference"/>
<attr name="seek_background" format="color" />
<attr name="ic_share" format="reference"/> <attr name="ic_share" format="reference"/>
<declare-styleable name="SquareImageView"> <declare-styleable name="SquareImageView">

View File

@ -22,6 +22,8 @@
<color name="highlight_dark">#43707070</color> <color name="highlight_dark">#43707070</color>
<color name="highlight_trueblack">#43707070</color> <color name="highlight_trueblack">#43707070</color>
<color name="non_square_icon_background">#22777777</color> <color name="non_square_icon_background">#22777777</color>
<color name="seek_background_light">#90000000</color>
<color name="seek_background_dark">#905B5B5B</color>
<color name="accent_light">#0078C2</color> <color name="accent_light">#0078C2</color>
<color name="accent_dark">#3D8BFF</color> <color name="accent_dark">#3D8BFF</color>

View File

@ -21,6 +21,7 @@
<item name="drawer_activated_color">@color/highlight_light</item> <item name="drawer_activated_color">@color/highlight_light</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
<item name="android:textColorHint">@color/grey600</item> <item name="android:textColorHint">@color/grey600</item>
<item name="seek_background">@color/seek_background_light</item>
<item name="storage">@drawable/ic_storage_black</item> <item name="storage">@drawable/ic_storage_black</item>
<item name="ic_network">@drawable/ic_network_black</item> <item name="ic_network">@drawable/ic_network_black</item>
@ -102,6 +103,7 @@
<item name="action_icon_color">@color/white</item> <item name="action_icon_color">@color/white</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
<item name="android:textColorHint">@color/medium_gray</item> <item name="android:textColorHint">@color/medium_gray</item>
<item name="seek_background">@color/seek_background_dark</item>
<item name="storage">@drawable/ic_storage_white</item> <item name="storage">@drawable/ic_storage_white</item>
<item name="ic_network">@drawable/ic_network_white</item> <item name="ic_network">@drawable/ic_network_white</item>