Colored Playback Controls
This commit is contained in:
parent
5e9ab35855
commit
a0ecf5a0fa
6 changed files with 113 additions and 35 deletions
|
|
@ -25,6 +25,15 @@
|
|||
|
||||
<p>You can view the changelog dialog again at any time from the <i>about</i> section.</p>
|
||||
|
||||
<h3>Version 0.9.43 beta3</h3>
|
||||
|
||||
<ol>
|
||||
<li><b>NEW:</b> "Colored Playback Controls". You can enable it from the settings to tint the
|
||||
play/pause, repeat and shuffle button as well as the progress slider with the album covers
|
||||
vibrant color.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h3>Version 0.9.43 beta2</h3>
|
||||
|
||||
<ol>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.kabouzeid.gramophone.ui.activities.base;
|
|||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
|
|
@ -42,7 +43,6 @@ import android.widget.SeekBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||
import com.kabouzeid.gramophone.dialogs.SleepTimerDialog;
|
||||
|
|
@ -90,7 +90,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private static final int CMD_REFRESH_PROGRESS_VIEWS = 1;
|
||||
|
||||
@Bind(R.id.play_pause_fab)
|
||||
FloatingActionButton playPauseFab;
|
||||
FloatingActionButton playPauseButton;
|
||||
@Bind(R.id.sliding_layout)
|
||||
SlidingUpPanelLayout slidingUpPanelLayout;
|
||||
|
||||
|
|
@ -142,6 +142,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
SeekBar progressSlider;
|
||||
|
||||
private int lastFooterColor;
|
||||
private int lastPlaybackControllsColor;
|
||||
private int lastTitleTextColor;
|
||||
private int lastCaptionTextColor;
|
||||
|
||||
|
|
@ -156,6 +157,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private boolean largerTitleBox;
|
||||
private boolean alternativeProgressSlider;
|
||||
private boolean showPlaybackControllerCard;
|
||||
private boolean colorPlaybackControls;
|
||||
|
||||
private Song song;
|
||||
|
||||
|
|
@ -163,19 +165,21 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
|
||||
private AnimatorSet colorTransitionAnimator;
|
||||
|
||||
private ArgbEvaluator argbEvaluator = new ArgbEvaluator();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(createContentView());
|
||||
ButterKnife.bind(this);
|
||||
|
||||
initAppearanceVarsFromSharedPrefs();
|
||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
||||
|
||||
setUpPlayPauseButton();
|
||||
setUpMiniPlayer();
|
||||
setUpSlidingPanel();
|
||||
|
||||
initAppearanceVarsFromSharedPrefs();
|
||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
||||
|
||||
adjustTitleBoxSize();
|
||||
setUpPlaybackControllerCard();
|
||||
setUpMusicControllers();
|
||||
|
|
@ -277,6 +281,13 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
showPlaybackControllerCard = PreferenceUtil.getInstance(this).playbackControllerCardNowPlaying();
|
||||
setUpPlaybackControllerCard();
|
||||
break;
|
||||
case PreferenceUtil.COLOR_PLAYBACK_CONTROLS_NOW_PLAYING:
|
||||
colorPlaybackControls = PreferenceUtil.getInstance(this).colorPlaybackControlsNowPlaying();
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
setUpProgressSliderTint();
|
||||
setUpPlayPauseButtonTint();
|
||||
break;
|
||||
case PreferenceUtil.HIDE_BOTTOM_BAR:
|
||||
recreate();
|
||||
break;
|
||||
|
|
@ -286,12 +297,9 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private void setUpPlayPauseButton() {
|
||||
updateFabState(false);
|
||||
|
||||
playPauseFab.setImageDrawable(playPauseDrawable);
|
||||
playPauseButton.setImageDrawable(playPauseDrawable);
|
||||
|
||||
int fabColor = getThemeColorAccent();
|
||||
int fabDrawableColor = ColorUtil.getDrawableColorForBackground(this, fabColor);
|
||||
playPauseFab.setBackgroundTintList(ColorStateList.valueOf(fabColor));
|
||||
playPauseFab.getDrawable().setColorFilter(fabDrawableColor, PorterDuff.Mode.SRC_IN);
|
||||
setUpPlayPauseButtonTint();
|
||||
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
|
|
@ -301,7 +309,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
}
|
||||
});
|
||||
|
||||
playPauseFab.setOnClickListener(new View.OnClickListener() {
|
||||
playPauseButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MusicPlayerRemote.getPosition() != -1) {
|
||||
|
|
@ -314,7 +322,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
}
|
||||
});
|
||||
|
||||
playPauseFab.setOnTouchListener(new View.OnTouchListener() {
|
||||
playPauseButton.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, @NonNull MotionEvent event) {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
|
|
@ -323,6 +331,17 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
});
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButtonTint() {
|
||||
int fabColor = colorPlaybackControls && slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED ? lastPlaybackControllsColor : getThemeColorAccent();
|
||||
setPlayPauseButtonTint(fabColor);
|
||||
}
|
||||
|
||||
private void setPlayPauseButtonTint(int color) {
|
||||
int fabDrawableColor = ColorUtil.getDrawableColorForBackground(this, color);
|
||||
playPauseButton.setBackgroundTintList(ColorStateList.valueOf(color));
|
||||
playPauseButton.getDrawable().setColorFilter(fabDrawableColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpMiniPlayer() {
|
||||
hideBottomBar(PreferenceUtil.getInstance(this).hideBottomBar());
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
|
||||
|
|
@ -375,13 +394,16 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
|
||||
@Override
|
||||
public void onPanelSlide(View view, float slideOffset) {
|
||||
float xTranslation = (dummyFab.getX() + mediaControllerContainer.getX() + footerFrame.getX() - playPauseFab.getLeft()) * slideOffset;
|
||||
float yTranslation = (dummyFab.getY() + mediaControllerContainer.getY() + footerFrame.getY() - playPauseFab.getTop()) * slideOffset;
|
||||
float xTranslation = (dummyFab.getX() + mediaControllerContainer.getX() + footerFrame.getX() - playPauseButton.getLeft()) * slideOffset;
|
||||
float yTranslation = (dummyFab.getY() + mediaControllerContainer.getY() + footerFrame.getY() - playPauseButton.getTop()) * slideOffset;
|
||||
|
||||
playPauseFab.setTranslationX(xTranslation);
|
||||
playPauseFab.setTranslationY(yTranslation);
|
||||
playPauseButton.setTranslationX(xTranslation);
|
||||
playPauseButton.setTranslationY(yTranslation);
|
||||
|
||||
miniPlayer.setAlpha(1 - slideOffset);
|
||||
|
||||
int newColor = colorPlaybackControls ? (int) argbEvaluator.evaluate(slideOffset, getThemeColorAccent(), lastPlaybackControllsColor) : getThemeColorAccent();
|
||||
setPlayPauseButtonTint(newColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -480,7 +502,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
} else {
|
||||
sharedViewsWithFab = new Pair[1];
|
||||
}
|
||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) playPauseFab, getString(R.string.transition_fab));
|
||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) playPauseButton, getString(R.string.transition_fab));
|
||||
return sharedViewsWithFab;
|
||||
}
|
||||
|
||||
|
|
@ -514,6 +536,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
largerTitleBox = PreferenceUtil.getInstance(this).largerTitleBoxNowPlaying();
|
||||
alternativeProgressSlider = PreferenceUtil.getInstance(this).alternativeProgressSliderNowPlaying();
|
||||
showPlaybackControllerCard = PreferenceUtil.getInstance(this).playbackControllerCardNowPlaying();
|
||||
colorPlaybackControls = PreferenceUtil.getInstance(this).colorPlaybackControlsNowPlaying();
|
||||
}
|
||||
|
||||
private void initProgressSliderDependentViews() {
|
||||
|
|
@ -572,18 +595,21 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private void setUpProgressSliderTint() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (alternativeProgressSlider) {
|
||||
progressSlider.setThumbTintList(ThemeSingleton.get().positiveColor);
|
||||
ColorStateList thumbTintList = colorPlaybackControls ? ColorStateList.valueOf(lastPlaybackControllsColor) : ThemeSingleton.get().positiveColor;
|
||||
progressSlider.setThumbTintList(thumbTintList);
|
||||
} else {
|
||||
final ColorStateList seekBarTint = ColorStateList.valueOf(getThemeColorAccent());
|
||||
final ColorStateList seekBarTint = colorPlaybackControls ? ColorStateList.valueOf(lastPlaybackControllsColor) : ColorStateList.valueOf(getThemeColorAccent());
|
||||
progressSlider.setThumbTintList(seekBarTint);
|
||||
progressSlider.setProgressTintList(seekBarTint);
|
||||
}
|
||||
} else {
|
||||
if (alternativeProgressSlider) {
|
||||
progressSlider.getThumb().setColorFilter(ThemeSingleton.get().positiveColor.getDefaultColor(), PorterDuff.Mode.SRC_IN);
|
||||
int color = colorPlaybackControls ? lastPlaybackControllsColor : ThemeSingleton.get().positiveColor.getDefaultColor();
|
||||
progressSlider.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
progressSlider.getThumb().setColorFilter(getThemeColorAccent(), PorterDuff.Mode.SRC_IN);
|
||||
progressSlider.getProgressDrawable().setColorFilter(getThemeColorAccent(), PorterDuff.Mode.SRC_IN);
|
||||
int color = colorPlaybackControls ? lastPlaybackControllsColor : getThemeColorAccent();
|
||||
progressSlider.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
progressSlider.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -636,12 +662,14 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
int activatedColor = colorPlaybackControls ? lastPlaybackControllsColor : ThemeSingleton.get().positiveColor.getDefaultColor();
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
ThemeSingleton.get().positiveColor.getDefaultColor()));
|
||||
activatedColor));
|
||||
break;
|
||||
default:
|
||||
int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
ColorUtil.resolveColor(this, android.R.attr.textColorSecondary)));
|
||||
deactivatedColor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -657,18 +685,20 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
}
|
||||
|
||||
private void updateRepeatState() {
|
||||
int activatedColor = colorPlaybackControls ? lastPlaybackControllsColor : ThemeSingleton.get().positiveColor.getDefaultColor();
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
DialogUtils.resolveColor(this, android.R.attr.textColorSecondary)));
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
ThemeSingleton.get().positiveColor.getDefaultColor()));
|
||||
activatedColor));
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
||||
activatedColor));
|
||||
break;
|
||||
default:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
||||
ThemeSingleton.get().positiveColor.getDefaultColor()));
|
||||
int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
deactivatedColor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -747,10 +777,10 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
|
||||
private void hideBottomBarIfQueueIsEmpty() {
|
||||
if (MusicPlayerRemote.getPlayingQueue().isEmpty()) {
|
||||
playPauseFab.setVisibility(View.GONE);
|
||||
playPauseButton.setVisibility(View.GONE);
|
||||
hideBottomBar(true);
|
||||
} else {
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseButton.setVisibility(View.VISIBLE);
|
||||
hideBottomBar(PreferenceUtil.getInstance(this).hideBottomBar());
|
||||
}
|
||||
}
|
||||
|
|
@ -862,6 +892,21 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
animatorSetBuilder.with(ViewUtil.createTextColorTransition(songTitle, lastTitleTextColor, titleTextColor));
|
||||
animatorSetBuilder.with(ViewUtil.createTextColorTransition(songText, lastCaptionTextColor, captionTextColor));
|
||||
|
||||
colorTransitionAnimator.addListener(new SimpleAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
if (newColor == ColorUtil.resolveColor(AbsSlidingMusicPanelActivity.this, R.attr.default_bar_color)) {
|
||||
lastPlaybackControllsColor = Color.WHITE;
|
||||
} else {
|
||||
lastPlaybackControllsColor = shiftColorDown(newColor);
|
||||
}
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
setUpProgressSliderTint();
|
||||
setUpPlayPauseButtonTint();
|
||||
}
|
||||
});
|
||||
|
||||
colorTransitionAnimator.start();
|
||||
|
||||
lastFooterColor = newColor;
|
||||
|
|
@ -869,6 +914,16 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
lastCaptionTextColor = captionTextColor;
|
||||
}
|
||||
|
||||
// note that this is not exactly the same as in ColorUtil
|
||||
@SuppressWarnings("ResourceType")
|
||||
private static int shiftColorDown(@ColorInt int color) {
|
||||
int alpha = Color.alpha(color);
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color, hsv);
|
||||
hsv[2] *= 0.5f; // value component
|
||||
return (alpha << 24) + (0x00ffffff & Color.HSVToColor(hsv));
|
||||
}
|
||||
|
||||
private void startUpdatingProgressViews() {
|
||||
queueNextRefresh(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public final class PreferenceUtil {
|
|||
public static final String LARGER_TITLE_BOX_NOW_PLAYING = "larger_title_box_now_playing";
|
||||
public static final String ALTERNATIVE_PROGRESS_SLIDER_NOW_PLAYING = "alternative_progress_slider_now_playing";
|
||||
public static final String PLAYBACK_CONTROLLER_CARD_NOW_PLAYING = "playback_controller_card_now_playing";
|
||||
public static final String COLOR_PLAYBACK_CONTROLS_NOW_PLAYING = "color_playback_controls_now_playing";
|
||||
|
||||
public static final String COLORED_NOTIFICATION = "colored_notification";
|
||||
|
||||
|
|
@ -169,6 +170,10 @@ public final class PreferenceUtil {
|
|||
return mPreferences.getBoolean(PLAYBACK_CONTROLLER_CARD_NOW_PLAYING, false);
|
||||
}
|
||||
|
||||
public final boolean colorPlaybackControlsNowPlaying() {
|
||||
return mPreferences.getBoolean(COLOR_PLAYBACK_CONTROLS_NOW_PLAYING, false);
|
||||
}
|
||||
|
||||
public final boolean largerTitleBoxNowPlaying() {
|
||||
return mPreferences.getBoolean(LARGER_TITLE_BOX_NOW_PLAYING, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@
|
|||
<string name="pref_title_opaque_statusbar_now_playing">Opaque Statusbar</string>
|
||||
<string name="pref_title_larger_title_box_now_playing">Larger Title Box</string>
|
||||
<string name="pref_title_alternative_progress_slider_now_playing">Alternative Progress Slider</string>
|
||||
<string name="pref_title_playback_controller_card_now_playing">Show Card below Playback Controllers</string>
|
||||
<string name="pref_title_playback_controller_card_now_playing">Show Card below Playback Controls</string>
|
||||
<string name="pref_title_colored_playback_controls_now_playing">Colored Playback Controls</string>
|
||||
<string name="pref_title_hide_bottom_bar">Hide Bottom Bar</string>
|
||||
<string name="no_equalizer">No equalizer found.</string>
|
||||
<string name="no_audio_ID">"No audio ID, play something and try again."</string>
|
||||
|
|
@ -157,6 +158,7 @@
|
|||
<string name="pref_summary_playback_controller_card_now_playing">Displays a card below the playback controller buttons (play/pause etc.).</string>
|
||||
<string name="pref_summary_ignore_media_store_artwork">Bypass the Media Store, which can increase the album artwork quality but causes slower image loading times. Only enable this if you have problems with low resolution artworks.</string>
|
||||
<string name="pref_summary_hide_bottom_bar">Hides the bar with the current playing information at the bottom. You can still fling the play/pause button in any direction to open the now playing view.</string>
|
||||
<string name="pref_summary_colored_playback_controls_now_playing">The play/pause, shuffle and repeat button as well as the progress slider are colored with the album cover\'s vibrant color.</string>
|
||||
<string name="could_not_download_album_cover">"Could not download a matching album cover."</string>
|
||||
<string name="search_hint">Search your library…</string>
|
||||
<string name="rescanning_media">Rescanning media…</string>
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@
|
|||
<item name="android:padding">12dp</item>
|
||||
<item name="android:layout_width">48dp</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
<!--<item name="android:scaleType">fitXY</item>-->
|
||||
<item name="android:background">?round_selector</item>
|
||||
<item name="android:layout_centerVertical">true</item>
|
||||
<item name="android:focusableInTouchMode">false</item>
|
||||
|
|
|
|||
|
|
@ -52,6 +52,14 @@
|
|||
android:title="@string/pref_title_playback_controller_card_now_playing"
|
||||
android:widgetLayout="@layout/preference_dynamic_checkbox" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="color_playback_controls_now_playing"
|
||||
android:layout="@layout/preference_custom"
|
||||
android:summary="@string/pref_summary_colored_playback_controls_now_playing"
|
||||
android:title="@string/pref_title_colored_playback_controls_now_playing"
|
||||
android:widgetLayout="@layout/preference_dynamic_checkbox" />
|
||||
|
||||
</com.kabouzeid.gramophone.prefs.DynamicPreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
Add table
Add a link
Reference in a new issue