Colored Playback Controls

This commit is contained in:
Karim Abou Zeid 2015-08-17 14:23:00 +02:00
commit a0ecf5a0fa
6 changed files with 113 additions and 35 deletions

View file

@ -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>

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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>

View file

@ -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>

View file

@ -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>