Sliding panel (early version, current implementation will probably replaced with a fragment implementation soon), translucent and colored statusbar for KitKat everywhere, use correct text colors for secondary texts, numerous clean ups
This commit is contained in:
parent
8f6e03f742
commit
5f0bfdb14b
65 changed files with 1247 additions and 1177 deletions
|
|
@ -4,7 +4,6 @@ import android.os.Build;
|
|||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
|
|
@ -25,7 +24,6 @@ import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
|
|||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.model.smartplaylist.AbsSmartPlaylist;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
|
|
@ -216,11 +214,8 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
|
|||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
Pair[] sharedViews = null;
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
sharedViews = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(null);
|
||||
Playlist playlist = dataSet.get(getAdapterPosition());
|
||||
NavigationUtil.goToPlaylist(activity, playlist, sharedViews);
|
||||
NavigationUtil.goToPlaylist(activity, playlist, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,12 +157,11 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
|
|||
private void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
int textColor = ColorUtil.getTextColorForBackground(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(textColor);
|
||||
holder.title.setTextColor(ColorUtil.getPrimaryTextColorForBackground(activity, color));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(textColor);
|
||||
holder.text.setTextColor(ColorUtil.getSecondaryTextColorForBackground(activity, color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +222,7 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
|
|||
activity.getResources().getString(R.string.transition_album_art)
|
||||
)};
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(albumPairs);
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).id, albumPairs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,12 +151,11 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
|
|||
private void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
int textColor = ColorUtil.getTextColorForBackground(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(textColor);
|
||||
holder.title.setTextColor(ColorUtil.getPrimaryTextColorForBackground(activity, color));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(textColor);
|
||||
holder.text.setTextColor(ColorUtil.getSecondaryTextColorForBackground(activity, color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +211,7 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
|
|||
activity.getResources().getString(R.string.transition_artist_image)
|
||||
)};
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
artistPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(artistPairs);
|
||||
artistPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(artistPairs);
|
||||
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).id, artistPairs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import com.kabouzeid.gramophone.util.MusicUtil;
|
|||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ import java.util.ArrayList;
|
|||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab.Callback {
|
||||
private static final int FADE_IN_TIME = 500;
|
||||
|
||||
@Nullable
|
||||
private final CabHolder cabHolder;
|
||||
|
|
@ -83,6 +85,7 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab
|
|||
.cacheInMemory(true)
|
||||
.showImageOnFail(R.drawable.default_album_art)
|
||||
.resetViewBeforeLoading(true)
|
||||
.displayer(new FadeInBitmapDisplayer(FADE_IN_TIME, true, true, false))
|
||||
.build()
|
||||
);
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab
|
|||
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_art))
|
||||
};
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(albumPairs);
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, song.albumId, albumPairs);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class SmartPlaylistSongAdapter extends SongAdapter {
|
|||
Pair.create(image, activity.getString(R.string.transition_album_art))
|
||||
};
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(albumPairs);
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,15 +124,10 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
|||
return bitmap;
|
||||
}
|
||||
})
|
||||
.displayer(new FadeInBitmapDisplayer(FADE_IN_TIME) {
|
||||
.displayer(new FadeInBitmapDisplayer(FADE_IN_TIME, true, true, false) {
|
||||
@Override
|
||||
public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
|
||||
boolean loadedFromMemoryCache = loadedFrom == LoadedFrom.MEMORY_CACHE;
|
||||
if (loadedFromMemoryCache) {
|
||||
imageAware.setImageBitmap(bitmap);
|
||||
} else {
|
||||
super.display(bitmap, imageAware, loadedFrom);
|
||||
}
|
||||
super.display(bitmap, imageAware, loadedFrom);
|
||||
if (usePalette)
|
||||
setColors(holder.paletteColor, holder);
|
||||
}
|
||||
|
|
@ -153,12 +148,11 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
|||
private void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
int textColor = ColorUtil.getTextColorForBackground(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(textColor);
|
||||
holder.title.setTextColor(ColorUtil.getPrimaryTextColorForBackground(activity, color));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(textColor);
|
||||
holder.text.setTextColor(ColorUtil.getSecondaryTextColorForBackground(activity, color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,7 +238,7 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
|||
Pair.create(image, activity.getResources().getString(R.string.transition_album_art))
|
||||
};
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(albumPairs);
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(albumPairs);
|
||||
NavigationUtil.goToAlbum(activity, getSong().albumId, albumPairs);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import android.widget.TextView;
|
|||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
|
|
@ -35,10 +36,10 @@ public class SongDetailDialog extends DialogFragment {
|
|||
public static final String TAG = SongDetailDialog.class.getSimpleName();
|
||||
|
||||
@NonNull
|
||||
public static SongDetailDialog create(File songFile) {
|
||||
public static SongDetailDialog create(Song song) {
|
||||
SongDetailDialog dialog = new SongDetailDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable("song_file", songFile);
|
||||
args.putSerializable("song", song);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
|
@ -47,7 +48,7 @@ public class SongDetailDialog extends DialogFragment {
|
|||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity context = getActivity();
|
||||
final File songFile = (File) getArguments().getSerializable("song_file");
|
||||
final Song song = (Song) getArguments().getSerializable("song");
|
||||
|
||||
MaterialDialog dialog = new MaterialDialog.Builder(context)
|
||||
.customView(R.layout.dialog_file_details, true)
|
||||
|
|
@ -73,17 +74,20 @@ public class SongDetailDialog extends DialogFragment {
|
|||
samplingRate.setText(makeTextWithTitle(context, R.string.label_sampling_rate, "-"));
|
||||
|
||||
try {
|
||||
if (songFile != null && songFile.exists()) {
|
||||
AudioFile audioFile = AudioFileIO.read(songFile);
|
||||
AudioHeader audioHeader = audioFile.getAudioHeader();
|
||||
if (song != null) {
|
||||
final File songFile = new File(song.data);
|
||||
if (songFile.exists()) {
|
||||
AudioFile audioFile = AudioFileIO.read(songFile);
|
||||
AudioHeader audioHeader = audioFile.getAudioHeader();
|
||||
|
||||
fileName.setText(makeTextWithTitle(context, R.string.label_file_name, songFile.getName()));
|
||||
filePath.setText(makeTextWithTitle(context, R.string.label_file_path, songFile.getAbsolutePath()));
|
||||
fileSize.setText(makeTextWithTitle(context, R.string.label_file_size, getFileSizeString(songFile.length())));
|
||||
fileFormat.setText(makeTextWithTitle(context, R.string.label_file_format, audioHeader.getFormat()));
|
||||
trackLength.setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(audioHeader.getTrackLength() * 1000)));
|
||||
bitRate.setText(makeTextWithTitle(context, R.string.label_bit_rate, audioHeader.getBitRate() + " kb/s"));
|
||||
samplingRate.setText(makeTextWithTitle(context, R.string.label_sampling_rate, audioHeader.getSampleRate() + " Hz"));
|
||||
fileName.setText(makeTextWithTitle(context, R.string.label_file_name, songFile.getName()));
|
||||
filePath.setText(makeTextWithTitle(context, R.string.label_file_path, songFile.getAbsolutePath()));
|
||||
fileSize.setText(makeTextWithTitle(context, R.string.label_file_size, getFileSizeString(songFile.length())));
|
||||
fileFormat.setText(makeTextWithTitle(context, R.string.label_file_format, audioHeader.getFormat()));
|
||||
trackLength.setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(audioHeader.getTrackLength() * 1000)));
|
||||
bitRate.setText(makeTextWithTitle(context, R.string.label_bit_rate, audioHeader.getBitRate() + " kb/s"));
|
||||
samplingRate.setText(makeTextWithTitle(context, R.string.label_sampling_rate, audioHeader.getSampleRate() + " Hz"));
|
||||
}
|
||||
}
|
||||
} catch (@NonNull CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
Log.e(TAG, "error while reading the song file", e);
|
||||
|
|
|
|||
|
|
@ -183,10 +183,11 @@ public class MusicPlayerRemote {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public static void seekTo(int millis) {
|
||||
public static int seekTo(int millis) {
|
||||
if (musicService != null) {
|
||||
musicService.seek(millis);
|
||||
return musicService.seek(millis);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getRepeatMode() {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
|||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
|
|
@ -57,19 +55,18 @@ public class SongMenuHelper {
|
|||
activity.startActivity(tagEditorIntent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
File songFile = new File(song.data);
|
||||
SongDetailDialog.create(songFile).show(activity.getSupportFragmentManager(), "SONG_DETAILS");
|
||||
SongDetailDialog.create(song).show(activity.getSupportFragmentManager(), "SONG_DETAILS");
|
||||
return true;
|
||||
case R.id.action_go_to_album:
|
||||
Pair[] albumPairs = null;
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(null);
|
||||
albumPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(null);
|
||||
NavigationUtil.goToAlbum(activity, song.albumId, albumPairs);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
Pair[] artistPairs = null;
|
||||
if (activity instanceof AbsSlidingMusicPanelActivity)
|
||||
artistPairs = ((AbsSlidingMusicPanelActivity) activity).getSharedViewsWithPlayPauseFab(null);
|
||||
artistPairs = ((AbsSlidingMusicPanelActivity) activity).addPlayPauseFabToSharedViews(null);
|
||||
NavigationUtil.goToArtist(activity, song.artistId, artistPairs);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ package com.kabouzeid.gramophone.interfaces;
|
|||
public interface MusicStateListener {
|
||||
void onPlayingMetaChanged();
|
||||
|
||||
|
||||
void onPlayStateChanged();
|
||||
|
||||
|
||||
void onMediaStoreChanged();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.kabouzeid.gramophone.misc;
|
||||
|
||||
import android.animation.Animator;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public abstract class SimpleAnimatorListener implements Animator.AnimatorListener {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
|||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class SmallObservableScrollViewCallbacks implements ObservableScrollViewCallbacks {
|
||||
public abstract class SimpleObservableScrollViewCallbacks implements ObservableScrollViewCallbacks {
|
||||
@Override
|
||||
public void onScrollChanged(int i, boolean b, boolean b2) {
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.kabouzeid.gramophone.misc;
|
||||
|
||||
import android.widget.SeekBar;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public abstract class SimpleOnSeekbarChangeListener implements SeekBar.OnSeekBarChangeListener {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import android.transition.Transition;
|
|||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
@TargetApi(21)
|
||||
public class SmallTransitionListener implements Transition.TransitionListener {
|
||||
public abstract class SimpleTransitionListener implements Transition.TransitionListener {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package com.kabouzeid.gramophone.misc;
|
||||
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class SmallOnGestureListener implements GestureDetector.OnGestureListener {
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,12 +24,9 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
MediaPlayer.OnCompletionListener {
|
||||
public static final String TAG = MultiPlayer.class.getSimpleName();
|
||||
|
||||
@NonNull
|
||||
private final WeakReference<MusicService> mService;
|
||||
|
||||
@Nullable
|
||||
private MediaPlayer mCurrentMediaPlayer = new MediaPlayer();
|
||||
@Nullable
|
||||
private MediaPlayer mNextMediaPlayer;
|
||||
|
||||
private Handler mHandler;
|
||||
|
|
|
|||
|
|
@ -741,9 +741,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
return player.duration();
|
||||
}
|
||||
|
||||
public void seek(int millis) {
|
||||
player.seek(millis);
|
||||
public int seek(int millis) {
|
||||
int newPosition = player.seek(millis);
|
||||
savePositionInTrack();
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
public void cycleRepeatMode() {
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import com.kabouzeid.gramophone.interfaces.CabHolder;
|
|||
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.misc.SimpleTransitionListener;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
|
|
@ -57,9 +57,7 @@ import butterknife.Bind;
|
|||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
||||
* <p/>
|
||||
* Should be kinda stable ONLY AS IT IS!!!
|
||||
* Be careful when changing things in this Activity!
|
||||
*/
|
||||
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
|
||||
|
||||
|
|
@ -97,7 +95,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_album_detail);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
|
@ -114,9 +111,14 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
animateFabCircularRevealOnEnterTransitionEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanelAndFab(R.layout.activity_album_detail);
|
||||
}
|
||||
|
||||
private void animateFabCircularRevealOnEnterTransitionEnd() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||
getWindow().getEnterTransition().addListener(new SimpleTransitionListener() {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
albumArtBackground.setVisibility(View.INVISIBLE);
|
||||
|
|
@ -140,11 +142,10 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
}
|
||||
}
|
||||
|
||||
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||
private final SimpleObservableScrollViewCallbacks observableScrollViewCallbacks = new SimpleObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
scrollY += albumArtViewHeight + titleViewHeight;
|
||||
super.onScrollChanged(scrollY, b, b2);
|
||||
float flexibleRange = albumArtViewHeight - headerOffset;
|
||||
|
||||
// Translate album cover
|
||||
|
|
@ -253,7 +254,7 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
private void setColors(int vibrantColor) {
|
||||
toolbarColor = vibrantColor;
|
||||
albumTitleView.setBackgroundColor(vibrantColor);
|
||||
albumTitleView.setTextColor(ColorUtil.getTextColorForBackground(vibrantColor));
|
||||
albumTitleView.setTextColor(ColorUtil.getPrimaryTextColorForBackground(this, vibrantColor));
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarColor(vibrantColor);
|
||||
|
|
@ -280,6 +281,7 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
public void run() {
|
||||
songsBackgroundView.getLayoutParams().height = contentView.getHeight();
|
||||
observableScrollViewCallbacks.onScrollChanged(-(albumArtViewHeight + titleViewHeight), false, false);
|
||||
// necessary to fix a bug
|
||||
recyclerView.scrollBy(0, 1);
|
||||
recyclerView.scrollBy(0, -1);
|
||||
}
|
||||
|
|
@ -350,19 +352,13 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
|
|||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
case R.id.action_now_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id);
|
||||
startActivityForResult(intent, TAG_EDITOR_REQUEST);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
Pair[] artistPairs = getSharedViewsWithPlayPauseFab(null);
|
||||
Pair[] artistPairs = addPlayPauseFabToSharedViews(null);
|
||||
NavigationUtil.goToArtist(this, album.artistId, artistPairs);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import com.kabouzeid.gramophone.lastfm.rest.model.artistinfo.ArtistInfo;
|
|||
import com.kabouzeid.gramophone.loader.ArtistAlbumLoader;
|
||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.misc.SimpleTransitionListener;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.model.Artist;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
|
@ -68,9 +68,7 @@ import retrofit.RetrofitError;
|
|||
import retrofit.client.Response;
|
||||
|
||||
/**
|
||||
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
||||
* <p/>
|
||||
* Should be kinda stable ONLY AS IT IS!!!
|
||||
* Be careful when changing things in this Activity!
|
||||
*/
|
||||
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
|
||||
|
||||
|
|
@ -114,13 +112,8 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_artist_detail);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
postponeEnterTransition();
|
||||
}
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
||||
|
||||
|
|
@ -137,12 +130,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
fixLollipopTransitionImageWrongSize();
|
||||
startPostponedEnterTransition();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||
getWindow().getEnterTransition().addListener(new SimpleTransitionListener() {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
artistImageBackground.setVisibility(View.INVISIBLE);
|
||||
|
|
@ -166,11 +154,15 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
}
|
||||
}
|
||||
|
||||
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanelAndFab(R.layout.activity_artist_detail);
|
||||
}
|
||||
|
||||
private final SimpleObservableScrollViewCallbacks observableScrollViewCallbacks = new SimpleObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
scrollY += artistImageViewHeight + titleViewHeight;
|
||||
super.onScrollChanged(scrollY, b, b2);
|
||||
float flexibleRange = artistImageViewHeight - headerOffset;
|
||||
|
||||
// Translate album cover
|
||||
|
|
@ -214,12 +206,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
private void setUpViews() {
|
||||
artistName.setText(artist.name);
|
||||
|
||||
ViewUtil.addOnGlobalLayoutListener(artistImage, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setUpArtistImageAndApplyPalette(false);
|
||||
}
|
||||
});
|
||||
setUpArtistImageAndApplyPalette(false);
|
||||
setUpSongListView();
|
||||
setUpAlbumRecyclerView();
|
||||
loadBiography();
|
||||
|
|
@ -377,7 +364,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
private void setColors(int vibrantColor) {
|
||||
toolbarColor = vibrantColor;
|
||||
artistName.setBackgroundColor(vibrantColor);
|
||||
artistName.setTextColor(ColorUtil.getTextColorForBackground(vibrantColor));
|
||||
artistName.setTextColor(ColorUtil.getPrimaryTextColorForBackground(this, vibrantColor));
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarColor(vibrantColor);
|
||||
|
|
@ -416,9 +403,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
case R.id.action_biography:
|
||||
if (biography != null) {
|
||||
getBiographyDialog().show();
|
||||
|
|
@ -430,9 +414,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating), Toast.LENGTH_SHORT).show();
|
||||
setUpArtistImageAndApplyPalette(true);
|
||||
return true;
|
||||
case R.id.action_now_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
@ -453,37 +434,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
albumRecyclerView.setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private void fixLollipopTransitionImageWrongSize() {
|
||||
getWindow().getSharedElementEnterTransition().addListener(new Transition.TransitionListener() {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
setUpArtistImageAndApplyPalette(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionCancel(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionPause(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionResume(Transition transition) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialCab openCab(int menuRes, @NonNull final MaterialCab.Callback callback) {
|
||||
if (cab != null && cab.isActive()) cab.finish();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
|
|
@ -17,7 +19,6 @@ import android.support.design.widget.AppBarLayout.OnOffsetChangedListener;
|
|||
import android.support.design.widget.NavigationView;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
|
|
@ -29,6 +30,7 @@ import android.view.Menu;
|
|||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
|
@ -51,16 +53,14 @@ import com.kabouzeid.gramophone.model.Song;
|
|||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AbsMainActivityFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AbsMainActivityRecyclerViewLayoutModeFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AlbumViewFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.ArtistViewFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.PlaylistViewFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.SongViewFragment;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
|
|
@ -97,15 +97,32 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
|
||||
Util.setStatusBarTranslucent(getWindow());
|
||||
drawerLayout.setFitsSystemWindows(false);
|
||||
navigationView.setFitsSystemWindows(false);
|
||||
findViewById(R.id.drawer_content_container).setFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
setUpDrawerLayout();
|
||||
setUpToolbar();
|
||||
setUpViewPager();
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarThemeColor();
|
||||
setStatusBarThemeColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
@SuppressLint("InflateParams")
|
||||
View contentView = getLayoutInflater().inflate(R.layout.activity_main_drawer_layout, null);
|
||||
ViewGroup drawerContent = ButterKnife.findById(contentView, R.id.drawer_content_container);
|
||||
drawerContent.addView(wrapSlidingMusicPanelAndFab(R.layout.activity_main_content));
|
||||
return contentView;
|
||||
}
|
||||
|
||||
private void setUpViewPager() {
|
||||
|
|
@ -258,7 +275,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
}
|
||||
|
||||
private void setUpDrawerLayout() {
|
||||
drawerLayout.setStatusBarBackgroundColor(getThemeColorPrimaryDarker());
|
||||
setUpNavigationView();
|
||||
}
|
||||
|
||||
|
|
@ -271,12 +287,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
navigationDrawerHeader.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//noinspection ConstantConditions
|
||||
NavigationUtil.openCurrentPlayingIfPossible(MainActivity.this, getSharedViewsWithPlayPauseFab(new Pair[]{
|
||||
Pair.create(navigationDrawerHeader.findViewById(R.id.image),
|
||||
getResources().getString(R.string.transition_album_art)
|
||||
)
|
||||
}));
|
||||
drawerLayout.closeDrawers();
|
||||
if (getSlidingUpPanelLayout().getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) {
|
||||
getSlidingUpPanelLayout().setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -391,12 +405,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
case R.id.action_search:
|
||||
startActivity(new Intent(MainActivity.this, SearchActivity.class));
|
||||
return true;
|
||||
case R.id.action_now_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
@ -524,38 +532,37 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
return pagerAdapter.getFragment(pager.getCurrentItem());
|
||||
}
|
||||
|
||||
private boolean isArtistPage() {
|
||||
return pager.getCurrentItem() == PagerAdapter.MusicFragments.ARTIST.ordinal();
|
||||
}
|
||||
|
||||
public ArtistViewFragment getArtistFragment() {
|
||||
return (ArtistViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.ARTIST.ordinal());
|
||||
}
|
||||
|
||||
private boolean isAlbumPage() {
|
||||
return pager.getCurrentItem() == PagerAdapter.MusicFragments.ALBUM.ordinal();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public AlbumViewFragment getAlbumFragment() {
|
||||
return (AlbumViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.ALBUM.ordinal());
|
||||
}
|
||||
|
||||
private boolean isSongPage() {
|
||||
return pager.getCurrentItem() == PagerAdapter.MusicFragments.SONG.ordinal();
|
||||
}
|
||||
|
||||
public SongViewFragment getSongFragment() {
|
||||
return (SongViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.SONG.ordinal());
|
||||
}
|
||||
// private boolean isArtistPage() {
|
||||
// return pager.getCurrentItem() == PagerAdapter.MusicFragments.ARTIST.ordinal();
|
||||
// }
|
||||
//
|
||||
// public ArtistViewFragment getArtistFragment() {
|
||||
// return (ArtistViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.ARTIST.ordinal());
|
||||
// }
|
||||
//
|
||||
// private boolean isAlbumPage() {
|
||||
// return pager.getCurrentItem() == PagerAdapter.MusicFragments.ALBUM.ordinal();
|
||||
// }
|
||||
//
|
||||
// public AlbumViewFragment getAlbumFragment() {
|
||||
// return (AlbumViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.ALBUM.ordinal());
|
||||
// }
|
||||
//
|
||||
// private boolean isSongPage() {
|
||||
// return pager.getCurrentItem() == PagerAdapter.MusicFragments.SONG.ordinal();
|
||||
// }
|
||||
//
|
||||
// public SongViewFragment getSongFragment() {
|
||||
// return (SongViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.SONG.ordinal());
|
||||
// }
|
||||
|
||||
private boolean isPlaylistPage() {
|
||||
return pager.getCurrentItem() == PagerAdapter.MusicFragments.PLAYLIST.ordinal();
|
||||
}
|
||||
|
||||
public PlaylistViewFragment getPlaylistFragment() {
|
||||
return (PlaylistViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.PLAYLIST.ordinal());
|
||||
}
|
||||
// public PlaylistViewFragment getPlaylistFragment() {
|
||||
// return (PlaylistViewFragment) pagerAdapter.getFragment(PagerAdapter.MusicFragments.PLAYLIST.ordinal());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
|
||||
|
|
@ -589,4 +596,16 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
public int getTotalAppBarScrollingRange() {
|
||||
return appbar.getTotalScrollRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelExpanded(View view) {
|
||||
super.onPanelExpanded(view);
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelCollapsed(View view) {
|
||||
super.onPanelCollapsed(view);
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,706 +0,0 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.transition.Transition;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
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;
|
||||
import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
|
||||
import com.kabouzeid.gramophone.dialogs.SongShareDialog;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.imageloader.BlurProcessor;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.service.MusicService;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import hugo.weaving.DebugLog;
|
||||
|
||||
public class MusicControllerActivity extends AbsSlidingMusicPanelActivity {
|
||||
|
||||
public static final String TAG = MusicControllerActivity.class.getSimpleName();
|
||||
private static final int FAB_CIRCULAR_REVEAL_ANIMATION_TIME = 1000;
|
||||
private static final int PROGRESS_VIEW_UPDATE_INTERVAL = 100;
|
||||
|
||||
private static final int CMD_UPDATE_PROGRESS_VIEWS = 1;
|
||||
|
||||
@Bind(R.id.title)
|
||||
TextView songTitle;
|
||||
@Bind(R.id.text)
|
||||
TextView songArtist;
|
||||
@Bind(R.id.footer)
|
||||
LinearLayout footer;
|
||||
@Bind(R.id.playback_controller_card)
|
||||
CardView playbackControllerCard;
|
||||
@Bind(R.id.prev_button)
|
||||
ImageButton prevButton;
|
||||
@Bind(R.id.next_button)
|
||||
ImageButton nextButton;
|
||||
@Bind(R.id.repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@Bind(R.id.shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@Bind(R.id.media_controller_container)
|
||||
RelativeLayout mediaControllerContainer;
|
||||
@Bind(R.id.album_art_background)
|
||||
ImageView albumArtBackground;
|
||||
@Bind(R.id.image)
|
||||
SquareIfPlaceImageView albumArt;
|
||||
@Bind(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@Bind(R.id.favorite_icon)
|
||||
ImageView favoriteIcon;
|
||||
|
||||
TextView songCurrentProgress;
|
||||
TextView songTotalTime;
|
||||
SeekBar progressSlider;
|
||||
|
||||
private int lastFooterColor = -1;
|
||||
private int lastTextColor = -2;
|
||||
|
||||
private Handler progressViewsUpdateHandler;
|
||||
private HandlerThread handlerThread;
|
||||
|
||||
private boolean opaqueStatusBar;
|
||||
private boolean opaqueToolBar;
|
||||
private boolean forceSquareAlbumArt;
|
||||
private boolean largerTitleBox;
|
||||
private boolean alternativeProgressSlider;
|
||||
private boolean showPlaybackControllerCard;
|
||||
|
||||
private Song song;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_music_controller);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
initAppearanceVarsFromSharedPrefs();
|
||||
initProgressSliderDependentViews();
|
||||
|
||||
moveSeekBarIntoPlace();
|
||||
adjustTitleBoxSize();
|
||||
setUpPlaybackControllerCard();
|
||||
setUpMusicControllers();
|
||||
setUpAlbumArtViews();
|
||||
setUpToolbar();
|
||||
animateFabCircularRevealOnEnterTransitionEnd();
|
||||
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
private void initProgressSliderDependentViews() {
|
||||
if (alternativeProgressSlider) {
|
||||
findViewById(R.id.default_progress_container).setVisibility(View.GONE);
|
||||
findViewById(R.id.default_progress_slider).setVisibility(View.GONE);
|
||||
findViewById(R.id.alternative_progress_container).setVisibility(View.VISIBLE);
|
||||
|
||||
songCurrentProgress = (TextView) findViewById(R.id.alternative_song_current_progress);
|
||||
songTotalTime = (TextView) findViewById(R.id.alternative_song_total_time);
|
||||
progressSlider = (SeekBar) findViewById(R.id.alternative_progress_slider);
|
||||
} else {
|
||||
songCurrentProgress = (TextView) findViewById(R.id.default_song_current_progress);
|
||||
songTotalTime = (TextView) findViewById(R.id.default_song_total_time);
|
||||
progressSlider = (SeekBar) findViewById(R.id.default_progress_slider);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpAlbumArtViews() {
|
||||
albumArtBackground.setAlpha(0.7f);
|
||||
albumArt.forceSquare(forceSquareAlbumArt);
|
||||
if (opaqueStatusBar) {
|
||||
if (opaqueToolBar) {
|
||||
alignAlbumArtToToolbar();
|
||||
} else {
|
||||
alignAlbumArtToStatusBar();
|
||||
}
|
||||
} else {
|
||||
alignAlbumArtToTop();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(null);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
}
|
||||
|
||||
private void animateFabCircularRevealOnEnterTransitionEnd() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
mediaControllerContainer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
int cx = (getPlayPauseFab().getLeft() + getPlayPauseFab().getRight()) / 2;
|
||||
int cy = (getPlayPauseFab().getTop() + getPlayPauseFab().getBottom()) / 2;
|
||||
int finalRadius = Math.max(mediaControllerContainer.getWidth(), mediaControllerContainer.getHeight());
|
||||
|
||||
Animator animator = ViewAnimationUtils.createCircularReveal(mediaControllerContainer, cx, cy, getPlayPauseFab().getWidth() / 2, finalRadius);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.setDuration(FAB_CIRCULAR_REVEAL_ANIMATION_TIME);
|
||||
animator.start();
|
||||
|
||||
mediaControllerContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void startHandler() {
|
||||
handlerThread = new HandlerThread("MusicProgressViewUpdateHandler",
|
||||
android.os.Process.THREAD_PRIORITY_BACKGROUND);
|
||||
handlerThread.start();
|
||||
progressViewsUpdateHandler = new MusicProgressViewsUpdateHandler(this, handlerThread.getLooper());
|
||||
}
|
||||
|
||||
private void stopHandler() {
|
||||
progressViewsUpdateHandler.removeCallbacksAndMessages(null);
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
handlerThread.quitSafely();
|
||||
} else {
|
||||
handlerThread.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private void startUpdatingProgressViews() {
|
||||
startHandler();
|
||||
progressViewsUpdateHandler.sendEmptyMessage(CMD_UPDATE_PROGRESS_VIEWS);
|
||||
}
|
||||
|
||||
private void stopUpdatingProgressViews() {
|
||||
progressViewsUpdateHandler.removeMessages(CMD_UPDATE_PROGRESS_VIEWS);
|
||||
stopHandler();
|
||||
}
|
||||
|
||||
private void initAppearanceVarsFromSharedPrefs() {
|
||||
opaqueStatusBar = PreferenceUtil.getInstance(this).opaqueStatusbarNowPlaying();
|
||||
opaqueToolBar = opaqueStatusBar && PreferenceUtil.getInstance(this).opaqueToolbarNowPlaying();
|
||||
forceSquareAlbumArt = PreferenceUtil.getInstance(this).forceAlbumArtSquared();
|
||||
largerTitleBox = PreferenceUtil.getInstance(this).largerTitleBoxNowPlaying();
|
||||
alternativeProgressSlider = PreferenceUtil.getInstance(this).alternativeProgressSliderNowPlaying();
|
||||
showPlaybackControllerCard = PreferenceUtil.getInstance(this).playbackControllerCardNowPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
getPlayPauseFab().setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
|
||||
private void moveSeekBarIntoPlace() {
|
||||
if (!alternativeProgressSlider) {
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
||||
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
|
||||
lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(progressSlider.getMeasuredHeight() / 2));
|
||||
progressSlider.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustTitleBoxSize() {
|
||||
int paddingTopBottom = largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_padding_large) : getResources().getDimensionPixelSize(R.dimen.title_box_padding_small);
|
||||
footer.setPadding(footer.getPaddingLeft(), paddingTopBottom, footer.getPaddingRight(), paddingTopBottom);
|
||||
|
||||
songTitle.setPadding(songTitle.getPaddingLeft(), songTitle.getPaddingTop(), songTitle.getPaddingRight(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small));
|
||||
songArtist.setPadding(songArtist.getPaddingLeft(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small), songArtist.getPaddingRight(), songArtist.getPaddingBottom());
|
||||
|
||||
songTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_small));
|
||||
songArtist.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_small));
|
||||
}
|
||||
|
||||
private void setUpPlaybackControllerCard() {
|
||||
playbackControllerCard.setVisibility(showPlaybackControllerCard ? View.VISIBLE : View.GONE);
|
||||
mediaControllerContainer.setBackgroundColor(showPlaybackControllerCard ? Color.TRANSPARENT : ColorUtil.resolveColor(this, R.attr.music_controller_container_color));
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setTint(@NonNull SeekBar seekBar, int color) {
|
||||
ColorStateList s1 = ColorStateList.valueOf(color);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
seekBar.setThumbTintList(s1);
|
||||
if (!alternativeProgressSlider) seekBar.setProgressTintList(s1);
|
||||
} else {
|
||||
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
if (!alternativeProgressSlider)
|
||||
seekBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
nextButton.setImageDrawable(Util.getTintedDrawable(this,
|
||||
R.drawable.ic_skip_next_white_36dp, DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
prevButton.setImageDrawable(Util.getTintedDrawable(this,
|
||||
R.drawable.ic_skip_previous_white_36dp, DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
}
|
||||
});
|
||||
prevButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.back();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
updateShuffleState();
|
||||
shuffleButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.toggleShuffleMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
updateRepeatState();
|
||||
repeatButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.cycleRepeatMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
default:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
startUpdatingProgressViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
stopUpdatingProgressViews();
|
||||
}
|
||||
|
||||
private void updateCurrentSong() {
|
||||
getCurrentSong();
|
||||
setHeadersText();
|
||||
setUpAlbumArtAndApplyPalette();
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(song.duration));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(0));
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private void setHeadersText() {
|
||||
songTitle.setText(song.title);
|
||||
songArtist.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean overridesTaskColor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setUpAlbumArtAndApplyPalette() {
|
||||
ImageLoader.getInstance().displayImage(
|
||||
MusicUtil.getSongImageLoaderString(song),
|
||||
albumArt,
|
||||
new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.showImageOnFail(R.drawable.default_album_art)
|
||||
.build(),
|
||||
new SimpleImageLoadingListener() {
|
||||
@DebugLog
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, @Nullable FailReason failReason) {
|
||||
applyPalette(null);
|
||||
|
||||
ImageLoader.getInstance().displayImage(
|
||||
"drawable://" + R.drawable.default_album_art,
|
||||
albumArtBackground,
|
||||
new DisplayImageOptions.Builder().postProcessor(new BlurProcessor(10)).build()
|
||||
);
|
||||
}
|
||||
|
||||
@DebugLog
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
||||
if (loadedImage == null) {
|
||||
onLoadingFailed(imageUri, view, null);
|
||||
return;
|
||||
}
|
||||
|
||||
applyPalette(loadedImage);
|
||||
|
||||
ImageLoader.getInstance().displayImage(
|
||||
imageUri,
|
||||
albumArtBackground,
|
||||
new DisplayImageOptions.Builder().postProcessor(new BlurProcessor(10)).build()
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void applyPalette(@Nullable Bitmap bitmap) {
|
||||
final int defaultBarColor = ColorUtil.resolveColor(this, R.attr.default_bar_color);
|
||||
if (bitmap != null) {
|
||||
Palette.from(bitmap)
|
||||
.resizeBitmapSize(100)
|
||||
.generate(new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(@NonNull Palette palette) {
|
||||
setColors(palette.getVibrantColor(defaultBarColor));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setColors(defaultBarColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void setColors(int vibrantColor) {
|
||||
animateColorChange(vibrantColor);
|
||||
animateTextColorChange(ColorUtil.getTextColorForBackground(vibrantColor));
|
||||
notifyTaskColorChange(vibrantColor);
|
||||
}
|
||||
|
||||
|
||||
private void animateColorChange(final int newColor) {
|
||||
if (lastFooterColor != -1 && lastFooterColor != newColor) {
|
||||
ViewUtil.animateViewColor(footer, lastFooterColor, newColor);
|
||||
|
||||
if (opaqueToolBar)
|
||||
ViewUtil.animateViewColor(toolbar, lastFooterColor, newColor);
|
||||
else toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
} else {
|
||||
footer.setBackgroundColor(newColor);
|
||||
|
||||
if (opaqueToolBar) toolbar.setBackgroundColor(newColor);
|
||||
else toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
setTint(progressSlider, !ThemeSingleton.get().darkTheme && getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent());
|
||||
if (opaqueStatusBar) setStatusBarColor(newColor);
|
||||
else setStatusBarColor(Color.TRANSPARENT);
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarColor(newColor);
|
||||
lastFooterColor = newColor;
|
||||
}
|
||||
|
||||
private void animateTextColorChange(final int newColor) {
|
||||
if (lastTextColor != -2 && lastTextColor != newColor) {
|
||||
ViewUtil.animateTextColor(songTitle, lastTextColor, newColor);
|
||||
ViewUtil.animateTextColor(songArtist, lastTextColor, newColor);
|
||||
} else {
|
||||
songTitle.setTextColor(newColor);
|
||||
songArtist.setTextColor(newColor);
|
||||
}
|
||||
lastTextColor = newColor;
|
||||
}
|
||||
|
||||
private void getCurrentSong() {
|
||||
song = MusicPlayerRemote.getCurrentSong();
|
||||
if (song.id == -1) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgressViews() {
|
||||
final int totalMillis = MusicPlayerRemote.getSongDurationMillis();
|
||||
final int progressMillis = MusicPlayerRemote.getSongProgressMillis();
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressSlider.setMax(totalMillis);
|
||||
progressSlider.setProgress(progressMillis);
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progressMillis));
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(totalMillis));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void animateSetFavorite() {
|
||||
favoriteIcon.clearAnimation();
|
||||
|
||||
favoriteIcon.setAlpha(0f);
|
||||
favoriteIcon.setScaleX(0f);
|
||||
favoriteIcon.setScaleY(0f);
|
||||
favoriteIcon.setVisibility(View.VISIBLE);
|
||||
favoriteIcon.setPivotX(favoriteIcon.getWidth() / 2);
|
||||
favoriteIcon.setPivotY(favoriteIcon.getHeight() / 2);
|
||||
|
||||
favoriteIcon.animate()
|
||||
.setDuration(600)
|
||||
.setInterpolator(new OvershootInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.setListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
favoriteIcon.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
})
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
favoriteIcon.animate()
|
||||
.setDuration(300)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.alpha(0f)
|
||||
.start();
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
super.onRepeatModeChanged();
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
super.onShuffleModeChanged();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_music_playing, menu);
|
||||
boolean isFavorite = MusicUtil.isFavorite(this, song);
|
||||
menu.findItem(R.id.action_toggle_favorite)
|
||||
.setIcon(isFavorite ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_favorite_outline_white_24dp)
|
||||
.setTitle(isFavorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_sleep_timer:
|
||||
new SleepTimerDialog().show(getSupportFragmentManager(), "SET_SLEEP_TIMER");
|
||||
return true;
|
||||
case R.id.action_toggle_favorite:
|
||||
MusicUtil.toggleFavorite(this, song);
|
||||
if (MusicUtil.isFavorite(this, song)) {
|
||||
animateSetFavorite();
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
return true;
|
||||
case R.id.action_share:
|
||||
SongShareDialog.create(song).show(getSupportFragmentManager(), "SHARE_SONG");
|
||||
return true;
|
||||
case R.id.action_equalizer:
|
||||
NavigationUtil.openEqualizer(this);
|
||||
return true;
|
||||
case R.id.action_shuffle_all:
|
||||
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(this), true);
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialog.create(song).show(getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||
return true;
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, SongTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
File songFile = new File(song.data);
|
||||
SongDetailDialog.create(songFile).show(getSupportFragmentManager(), "SONG_DETAIL");
|
||||
return true;
|
||||
case R.id.action_go_to_album:
|
||||
NavigationUtil.goToAlbum(this, song.albumId, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
NavigationUtil.goToArtist(this, song.artistId, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void alignAlbumArtToTop() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.album_art_frame).getLayoutParams();
|
||||
if (Build.VERSION.SDK_INT > 16) {
|
||||
params.removeRule(RelativeLayout.BELOW);
|
||||
} else {
|
||||
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
params.addRule(RelativeLayout.ABOVE, R.id.footer_frame);
|
||||
}
|
||||
}
|
||||
|
||||
private void alignAlbumArtToToolbar() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.album_art_frame).getLayoutParams();
|
||||
params.addRule(RelativeLayout.BELOW, R.id.toolbar);
|
||||
}
|
||||
|
||||
private void alignAlbumArtToStatusBar() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.album_art_frame).getLayoutParams();
|
||||
params.addRule(RelativeLayout.BELOW, R.id.status_bar);
|
||||
}
|
||||
|
||||
private static class MusicProgressViewsUpdateHandler extends Handler {
|
||||
private WeakReference<MusicControllerActivity> activityReference;
|
||||
|
||||
public MusicProgressViewsUpdateHandler(final MusicControllerActivity activity, @NonNull final Looper looper) {
|
||||
super(looper);
|
||||
activityReference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
if (msg.what == CMD_UPDATE_PROGRESS_VIEWS) {
|
||||
activityReference.get().updateProgressViews();
|
||||
sendEmptyMessageDelayed(CMD_UPDATE_PROGRESS_VIEWS, PROGRESS_VIEW_UPDATE_INTERVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,8 +54,8 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_playlist_detail);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
getIntentExtras();
|
||||
|
|
@ -71,6 +71,11 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
|
|||
setStatusBarThemeColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanelAndFab(R.layout.activity_playlist_detail);
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||
if (playlist instanceof AbsSmartPlaylist) {
|
||||
|
|
@ -168,12 +173,6 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
|
|||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
case R.id.action_now_playing:
|
||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithPlayPauseFab(null));
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
NavigationUtil.openPlayingQueueDialog(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public class SearchActivity extends AbsMusicStateActivity {
|
|||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
setTitle(null);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search);
|
||||
|
|
@ -71,7 +72,8 @@ public class SearchActivity extends AbsMusicStateActivity {
|
|||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
setNavigationBarThemeColor();
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarThemeColor();
|
||||
setStatusBarThemeColor();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
setStatusBarTransparent();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_preferences);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public abstract class AbsMusicStateActivity extends AbsBaseActivity implements S
|
|||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
onPlayStateChanged();
|
||||
onRepeatModeChanged();
|
||||
onShuffleModeChanged();
|
||||
onPlayingMetaChanged();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,64 +1,223 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.base;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.util.Log;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.TypedValue;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.misc.SmallOnGestureListener;
|
||||
import com.kabouzeid.gramophone.imageloader.BlurProcessor;
|
||||
import com.kabouzeid.gramophone.misc.SimpleOnSeekbarChangeListener;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.service.MusicService;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
|
||||
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
* <p/>
|
||||
* Do not use {@link #setContentView(int)} but wrap your layout with
|
||||
* {@link #wrapSlidingMusicPanelAndFab(int)} first and then return it in {@link #createContentView()}
|
||||
*/
|
||||
public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity {
|
||||
public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity implements SlidingUpPanelLayout.PanelSlideListener {
|
||||
public static final String TAG = AbsSlidingMusicPanelActivity.class.getSimpleName();
|
||||
|
||||
private static final int FAB_CIRCULAR_REVEAL_ANIMATION_TIME = 1000;
|
||||
private static final long DEFAULT_PROGRESS_VIEW_REFRESH_INTERVAL = 500;
|
||||
private static final int CMD_REFRESH_PROGRESS_VIEWS = 1;
|
||||
|
||||
@Bind(R.id.play_pause_fab)
|
||||
FloatingActionButton playPauseFab;
|
||||
@Bind(R.id.sliding_layout)
|
||||
SlidingUpPanelLayout slidingUpPanelLayout;
|
||||
|
||||
@Bind(R.id.mini_player)
|
||||
FrameLayout miniPlayer;
|
||||
@Bind(R.id.mini_player_title)
|
||||
TextView miniPlayerTitle;
|
||||
@Bind(R.id.mini_player_image)
|
||||
ImageView miniPlayerImage;
|
||||
|
||||
@Bind(R.id.player_dummy_fab)
|
||||
View dummyFab;
|
||||
|
||||
@Bind(R.id.player_title)
|
||||
TextView songTitle;
|
||||
@Bind(R.id.player_text)
|
||||
TextView songText;
|
||||
@Bind(R.id.player_footer)
|
||||
LinearLayout footer;
|
||||
@Bind(R.id.player_playback_controller_card)
|
||||
CardView playbackControllerCard;
|
||||
@Bind(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@Bind(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@Bind(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@Bind(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@Bind(R.id.player_media_controller_container)
|
||||
RelativeLayout mediaControllerContainer;
|
||||
@Bind(R.id.player_footer_frame)
|
||||
LinearLayout footerFrame;
|
||||
@Bind(R.id.player_album_art_background)
|
||||
ImageView albumArtBackground;
|
||||
@Bind(R.id.player_image)
|
||||
SquareIfPlaceImageView albumArt;
|
||||
@Bind(R.id.player_status_bar)
|
||||
View playerStatusbar;
|
||||
@Bind(R.id.player_toolbar)
|
||||
Toolbar playerToolbar;
|
||||
@Bind(R.id.player_favorite_icon)
|
||||
ImageView favoriteIcon;
|
||||
|
||||
TextView songCurrentProgress;
|
||||
TextView songTotalTime;
|
||||
SeekBar seekBar;
|
||||
|
||||
private int lastFooterColor = -1;
|
||||
private int lastTitleTextColor = -2;
|
||||
private int lastCaptionTextColor = -2;
|
||||
|
||||
private Handler progressViewsUpdateHandler;
|
||||
|
||||
private boolean opaqueStatusBar;
|
||||
private boolean opaqueToolBar;
|
||||
private boolean forceSquareAlbumArt;
|
||||
private boolean largerTitleBox;
|
||||
private boolean alternativeProgressSlider;
|
||||
private boolean showPlaybackControllerCard;
|
||||
|
||||
private Song song;
|
||||
|
||||
private PlayPauseDrawable playPauseDrawable;
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(createContentView());
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setUpPlayPauseButton();
|
||||
setUpMiniPlayer();
|
||||
setUpSlidingPanel();
|
||||
|
||||
initAppearanceVarsFromSharedPrefs();
|
||||
initProgressSliderDependentViews();
|
||||
|
||||
moveSeekBarIntoPlace();
|
||||
adjustTitleBoxSize();
|
||||
setUpPlaybackControllerCard();
|
||||
setUpMusicControllers();
|
||||
setUpAlbumArtViews();
|
||||
setUpPlayerToolbar();
|
||||
|
||||
progressViewsUpdateHandler = new MusicProgressViewsUpdateHandler(this);
|
||||
}
|
||||
|
||||
protected abstract View createContentView();
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
|
||||
startUpdatingProgressViews();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
stopUpdatingProgressViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
super.onRepeatModeChanged();
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
super.onShuffleModeChanged();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
updateFabState(false);
|
||||
|
||||
getPlayPauseFab().setImageDrawable(playPauseDrawable);
|
||||
playPauseFab.setImageDrawable(playPauseDrawable);
|
||||
final int accentColor = ThemeSingleton.get().positiveColor;
|
||||
getPlayPauseFab().setBackgroundTintList(ColorUtil.getEmptyColorStateList(accentColor));
|
||||
playPauseFab.setBackgroundTintList(ColorUtil.getEmptyColorStateList(accentColor));
|
||||
if (accentColor == Color.WHITE) {
|
||||
getPlayPauseFab().getDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
playPauseFab.getDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
getPlayPauseFab().getDrawable().clearColorFilter();
|
||||
playPauseFab.getDrawable().clearColorFilter();
|
||||
}
|
||||
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new SmallOnGestureListener() {
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
NavigationUtil.openCurrentPlayingIfPossible(AbsSlidingMusicPanelActivity.this, getSharedViewsWithPlayPauseFab(null));
|
||||
toggleSlidingPanel();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
getPlayPauseFab().setOnClickListener(new View.OnClickListener() {
|
||||
playPauseFab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (MusicPlayerRemote.getPosition() != -1) {
|
||||
|
|
@ -73,26 +232,129 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity
|
|||
}
|
||||
});
|
||||
|
||||
getPlayPauseFab().setOnTouchListener(new View.OnTouchListener() {
|
||||
playPauseFab.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, @NonNull MotionEvent event) {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPlayPauseFab().setOnLongClickListener(new View.OnLongClickListener() {
|
||||
private void setUpMiniPlayer() {
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
if (song.id != -1) {
|
||||
Toast.makeText(AbsSlidingMusicPanelActivity.this, song.title + " - " + song.artistName, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(AbsSlidingMusicPanelActivity.this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show();
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
if (Math.abs(velocityX) > Math.abs(velocityY)) {
|
||||
if (velocityX < 0) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
return true;
|
||||
} else if (velocityX > 0) {
|
||||
MusicPlayerRemote.back();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
miniPlayer.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
});
|
||||
|
||||
miniPlayer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
toggleSlidingPanel();
|
||||
}
|
||||
});
|
||||
|
||||
setMiniPlayerColor(ColorUtil.resolveColor(this, R.attr.card_color));
|
||||
|
||||
miniPlayerImage.setImageResource(R.drawable.ic_equalizer_white_24dp);
|
||||
miniPlayerImage.setColorFilter(ColorUtil.resolveColor(this, R.attr.themed_drawable_color));
|
||||
}
|
||||
|
||||
public void setMiniPlayerColor(int color) {
|
||||
miniPlayer.setBackgroundColor(color);
|
||||
miniPlayerTitle.setTextColor(ColorUtil.getPrimaryTextColorForBackground(this, color));
|
||||
}
|
||||
|
||||
private void setUpSlidingPanel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mediaControllerContainer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
slidingUpPanelLayout.setPanelSlideListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelSlide(View view, float slideOffset) {
|
||||
miniPlayer.setAlpha(1 - slideOffset);
|
||||
|
||||
float xTranslation = (dummyFab.getX() + mediaControllerContainer.getX() + footerFrame.getX() - playPauseFab.getLeft()) * slideOffset;
|
||||
float yTranslation = (dummyFab.getY() + mediaControllerContainer.getY() + footerFrame.getY() - playPauseFab.getTop()) * slideOffset;
|
||||
|
||||
playPauseFab.setTranslationX(xTranslation);
|
||||
playPauseFab.setTranslationY(yTranslation);
|
||||
|
||||
if (slideOffset > 0 && !progressViewsUpdateHandler.hasMessages(CMD_REFRESH_PROGRESS_VIEWS)) {
|
||||
startUpdatingProgressViews();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelCollapsed(View view) {
|
||||
stopUpdatingProgressViews();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mediaControllerContainer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelExpanded(View view) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (mediaControllerContainer.getVisibility() == View.INVISIBLE) {
|
||||
int cx = (dummyFab.getLeft() + dummyFab.getRight()) / 2;
|
||||
int cy = (dummyFab.getTop() + dummyFab.getBottom()) / 2;
|
||||
int finalRadius = Math.max(mediaControllerContainer.getWidth(), mediaControllerContainer.getHeight());
|
||||
|
||||
Animator animator = ViewAnimationUtils.createCircularReveal(mediaControllerContainer, cx, cy, dummyFab.getWidth() / 2, finalRadius);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.setDuration(FAB_CIRCULAR_REVEAL_ANIMATION_TIME);
|
||||
animator.start();
|
||||
|
||||
mediaControllerContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelAnchored(View view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelHidden(View view) {
|
||||
|
||||
}
|
||||
|
||||
private void toggleSlidingPanel() {
|
||||
if (slidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
|
||||
} else {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
|
||||
}
|
||||
}
|
||||
|
||||
public FloatingActionButton getPlayPauseFab() {
|
||||
return playPauseFab;
|
||||
}
|
||||
|
||||
public SlidingUpPanelLayout getSlidingUpPanelLayout() {
|
||||
return slidingUpPanelLayout;
|
||||
}
|
||||
|
||||
protected void updateFabState(boolean animate) {
|
||||
|
|
@ -106,19 +368,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity
|
|||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected FloatingActionButton getPlayPauseFab() {
|
||||
if (playPauseFab == null) {
|
||||
playPauseFab = (FloatingActionButton) findViewById(R.id.play_pause_fab);
|
||||
if (playPauseFab == null) {
|
||||
playPauseFab = new FloatingActionButton(this);
|
||||
Log.e(TAG, "PlayPauseFAB not found, created default FAB.");
|
||||
}
|
||||
}
|
||||
return playPauseFab;
|
||||
}
|
||||
|
||||
public Pair[] getSharedViewsWithPlayPauseFab(@Nullable Pair[] sharedViews) {
|
||||
public Pair[] addPlayPauseFabToSharedViews(@Nullable Pair[] sharedViews) {
|
||||
Pair[] sharedViewsWithFab;
|
||||
if (sharedViews != null) {
|
||||
sharedViewsWithFab = new Pair[sharedViews.length + 1];
|
||||
|
|
@ -126,7 +376,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity
|
|||
} else {
|
||||
sharedViewsWithFab = new Pair[1];
|
||||
}
|
||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) getPlayPauseFab(), getString(R.string.transition_fab));
|
||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) playPauseFab, getString(R.string.transition_fab));
|
||||
return sharedViewsWithFab;
|
||||
}
|
||||
|
||||
|
|
@ -135,4 +385,509 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicStateActivity
|
|||
super.onPlayStateChanged();
|
||||
updateFabState(true);
|
||||
}
|
||||
|
||||
protected View wrapSlidingMusicPanelAndFab(@LayoutRes int resId) {
|
||||
@SuppressLint("InflateParams")
|
||||
View slidingMusicPanelLayout = getLayoutInflater().inflate(R.layout.sliding_music_panel_layout, null);
|
||||
ViewGroup contentContainer = ButterKnife.findById(slidingMusicPanelLayout, R.id.content_container);
|
||||
getLayoutInflater().inflate(resId, contentContainer);
|
||||
return slidingMusicPanelLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (slidingUpPanelLayout.getPanelState() != SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private void initAppearanceVarsFromSharedPrefs() {
|
||||
opaqueStatusBar = PreferenceUtil.getInstance(this).opaqueStatusbarNowPlaying();
|
||||
opaqueToolBar = opaqueStatusBar && PreferenceUtil.getInstance(this).opaqueToolbarNowPlaying();
|
||||
forceSquareAlbumArt = PreferenceUtil.getInstance(this).forceAlbumArtSquared();
|
||||
largerTitleBox = PreferenceUtil.getInstance(this).largerTitleBoxNowPlaying();
|
||||
alternativeProgressSlider = PreferenceUtil.getInstance(this).alternativeProgressSliderNowPlaying();
|
||||
showPlaybackControllerCard = PreferenceUtil.getInstance(this).playbackControllerCardNowPlaying();
|
||||
}
|
||||
|
||||
private void initProgressSliderDependentViews() {
|
||||
if (alternativeProgressSlider) {
|
||||
findViewById(R.id.player_default_progress_container).setVisibility(View.GONE);
|
||||
findViewById(R.id.player_default_progress_slider).setVisibility(View.GONE);
|
||||
findViewById(R.id.player_alternative_progress_container).setVisibility(View.VISIBLE);
|
||||
|
||||
songCurrentProgress = (TextView) findViewById(R.id.player_alternative_song_current_progress);
|
||||
songTotalTime = (TextView) findViewById(R.id.player_alternative_song_total_time);
|
||||
seekBar = (SeekBar) findViewById(R.id.player_alternative_progress_slider);
|
||||
} else {
|
||||
songCurrentProgress = (TextView) findViewById(R.id.player_default_song_current_progress);
|
||||
songTotalTime = (TextView) findViewById(R.id.player_default_song_total_time);
|
||||
seekBar = (SeekBar) findViewById(R.id.player_default_progress_slider);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveSeekBarIntoPlace() {
|
||||
if (!alternativeProgressSlider) {
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) seekBar.getLayoutParams();
|
||||
seekBar.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
|
||||
lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(seekBar.getMeasuredHeight() / 2));
|
||||
seekBar.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustTitleBoxSize() {
|
||||
int paddingTopBottom = largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_padding_large) : getResources().getDimensionPixelSize(R.dimen.title_box_padding_small);
|
||||
footer.setPadding(footer.getPaddingLeft(), paddingTopBottom, footer.getPaddingRight(), paddingTopBottom);
|
||||
|
||||
songTitle.setPadding(songTitle.getPaddingLeft(), songTitle.getPaddingTop(), songTitle.getPaddingRight(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small));
|
||||
songText.setPadding(songText.getPaddingLeft(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small), songText.getPaddingRight(), songText.getPaddingBottom());
|
||||
|
||||
songTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_small));
|
||||
songText.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_small));
|
||||
}
|
||||
|
||||
private void setUpPlaybackControllerCard() {
|
||||
playbackControllerCard.setVisibility(showPlaybackControllerCard ? View.VISIBLE : View.GONE);
|
||||
mediaControllerContainer.setBackgroundColor(showPlaybackControllerCard ? Color.TRANSPARENT : ColorUtil.resolveColor(this, R.attr.music_controller_container_color));
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpSeekBar();
|
||||
}
|
||||
|
||||
private void setTint(@NonNull SeekBar seekBar, int color) {
|
||||
ColorStateList s1 = ColorStateList.valueOf(color);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
seekBar.setThumbTintList(s1);
|
||||
if (!alternativeProgressSlider) seekBar.setProgressTintList(s1);
|
||||
} else {
|
||||
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
if (!alternativeProgressSlider)
|
||||
seekBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpSeekBar() {
|
||||
setTint(seekBar, !ThemeSingleton.get().darkTheme && getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent());
|
||||
seekBar.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
refreshProgressViews();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
int themedDrawableColor = ColorUtil.resolveColor(this, R.attr.themed_drawable_color);
|
||||
nextButton.setImageDrawable(Util.getTintedDrawable(this,
|
||||
R.drawable.ic_skip_next_white_36dp, themedDrawableColor));
|
||||
prevButton.setImageDrawable(Util.getTintedDrawable(this,
|
||||
R.drawable.ic_skip_previous_white_36dp, themedDrawableColor));
|
||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
}
|
||||
});
|
||||
prevButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.back();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
updateShuffleState();
|
||||
shuffleButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.toggleShuffleMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||
DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
updateRepeatState();
|
||||
repeatButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MusicPlayerRemote.cycleRepeatMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
DialogUtils.resolveColor(this, R.attr.themed_drawable_color)));
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
default:
|
||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
||||
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpAlbumArtViews() {
|
||||
albumArtBackground.setAlpha(0.7f);
|
||||
albumArt.forceSquare(forceSquareAlbumArt);
|
||||
if (opaqueStatusBar) {
|
||||
if (opaqueToolBar) {
|
||||
alignAlbumArtToToolbar();
|
||||
} else {
|
||||
alignAlbumArtToStatusBar();
|
||||
}
|
||||
} else {
|
||||
alignAlbumArtToTop();
|
||||
}
|
||||
}
|
||||
|
||||
private void alignAlbumArtToTop() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.player_album_art_frame).getLayoutParams();
|
||||
if (Build.VERSION.SDK_INT > 16) {
|
||||
params.removeRule(RelativeLayout.BELOW);
|
||||
} else {
|
||||
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
params.addRule(RelativeLayout.ABOVE, R.id.player_footer_frame);
|
||||
}
|
||||
}
|
||||
|
||||
private void alignAlbumArtToToolbar() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.player_album_art_frame).getLayoutParams();
|
||||
params.addRule(RelativeLayout.BELOW, R.id.player_toolbar);
|
||||
}
|
||||
|
||||
private void alignAlbumArtToStatusBar() {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.player_album_art_frame).getLayoutParams();
|
||||
params.addRule(RelativeLayout.BELOW, R.id.player_status_bar);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
// TODO setUpPlayerToolbar
|
||||
}
|
||||
|
||||
private void updateCurrentSong() {
|
||||
getCurrentSong();
|
||||
updateMiniPlayerAndHeaderText();
|
||||
setUpAlbumArtAndApplyPalette();
|
||||
// TODO invalidateOptionsMenu() for the custom player menu
|
||||
}
|
||||
|
||||
private void getCurrentSong() {
|
||||
song = MusicPlayerRemote.getCurrentSong();
|
||||
if (song.id == -1) {
|
||||
// TODO disable and hide sliding panel & fab
|
||||
} else {
|
||||
// TODO enable and show sliding panel & fab
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMiniPlayerAndHeaderText() {
|
||||
songTitle.setText(song.title);
|
||||
songText.setText(song.artistName);
|
||||
|
||||
miniPlayerTitle.setText(song.title);
|
||||
}
|
||||
|
||||
private void setUpAlbumArtAndApplyPalette() {
|
||||
ImageLoader.getInstance().displayImage(
|
||||
MusicUtil.getSongImageLoaderString(song),
|
||||
albumArt,
|
||||
new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.showImageOnFail(R.drawable.default_album_art)
|
||||
.build(),
|
||||
new SimpleImageLoadingListener() {
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, @Nullable FailReason failReason) {
|
||||
applyPalette(null);
|
||||
|
||||
ImageLoader.getInstance().displayImage(
|
||||
"drawable://" + R.drawable.default_album_art,
|
||||
albumArtBackground,
|
||||
new DisplayImageOptions.Builder().postProcessor(new BlurProcessor(10)).build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
||||
if (loadedImage == null) {
|
||||
onLoadingFailed(imageUri, view, null);
|
||||
return;
|
||||
}
|
||||
|
||||
applyPalette(loadedImage);
|
||||
|
||||
ImageLoader.getInstance().displayImage(
|
||||
imageUri,
|
||||
albumArtBackground,
|
||||
new DisplayImageOptions.Builder().postProcessor(new BlurProcessor(10)).build()
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void applyPalette(@Nullable Bitmap bitmap) {
|
||||
final int defaultBarColor = ColorUtil.resolveColor(this, R.attr.default_bar_color);
|
||||
if (bitmap != null) {
|
||||
Palette.from(bitmap)
|
||||
.resizeBitmapSize(100)
|
||||
.generate(new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(@NonNull Palette palette) {
|
||||
setColors(palette.getVibrantColor(defaultBarColor));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setColors(defaultBarColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void setColors(int color) {
|
||||
animateColorChange(color);
|
||||
animateTextColorChange(ColorUtil.getPrimaryTextColorForBackground(this, color), ColorUtil.getSecondaryTextColorForBackground(this, color));
|
||||
}
|
||||
|
||||
private void animateColorChange(final int newColor) {
|
||||
if (lastFooterColor != -1 && lastFooterColor != newColor) {
|
||||
ViewUtil.animateViewColor(footer, lastFooterColor, newColor);
|
||||
|
||||
if (opaqueToolBar) {
|
||||
ViewUtil.animateViewColor(playerToolbar, lastFooterColor, newColor);
|
||||
} else {
|
||||
playerToolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
if (opaqueStatusBar) {
|
||||
int newStatusbarColor = newColor;
|
||||
int oldStatusbarColor = lastFooterColor;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
newStatusbarColor = ColorUtil.shiftColorDown(newStatusbarColor);
|
||||
oldStatusbarColor = ColorUtil.shiftColorDown(oldStatusbarColor);
|
||||
}
|
||||
ViewUtil.animateViewColor(playerStatusbar, oldStatusbarColor, newStatusbarColor);
|
||||
} else {
|
||||
playerStatusbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
} else {
|
||||
footer.setBackgroundColor(newColor);
|
||||
|
||||
if (opaqueToolBar) {
|
||||
playerToolbar.setBackgroundColor(newColor);
|
||||
} else {
|
||||
playerToolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
if (opaqueStatusBar) {
|
||||
int newStatusbarColor = newColor;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
newStatusbarColor = ColorUtil.shiftColorDown(newColor);
|
||||
}
|
||||
playerStatusbar.setBackgroundColor(newStatusbarColor);
|
||||
} else {
|
||||
playerStatusbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldColorNavigationBar())
|
||||
setNavigationBarColor(newColor);
|
||||
lastFooterColor = newColor;
|
||||
}
|
||||
|
||||
private void animateTextColorChange(int titleTextColor, int captionTextColor) {
|
||||
if (lastTitleTextColor != -2 && lastTitleTextColor != titleTextColor) {
|
||||
ViewUtil.animateTextColor(songTitle, lastTitleTextColor, titleTextColor);
|
||||
} else {
|
||||
songTitle.setTextColor(titleTextColor);
|
||||
}
|
||||
if (lastCaptionTextColor != -2 && lastCaptionTextColor != captionTextColor) {
|
||||
ViewUtil.animateTextColor(songText, lastCaptionTextColor, captionTextColor);
|
||||
} else {
|
||||
songText.setTextColor(captionTextColor);
|
||||
}
|
||||
lastTitleTextColor = titleTextColor;
|
||||
lastCaptionTextColor = captionTextColor;
|
||||
}
|
||||
|
||||
private void startUpdatingProgressViews() {
|
||||
queueNextRefresh(0);
|
||||
}
|
||||
|
||||
private void stopUpdatingProgressViews() {
|
||||
progressViewsUpdateHandler.removeMessages(CMD_REFRESH_PROGRESS_VIEWS);
|
||||
}
|
||||
|
||||
private void queueNextRefresh(final long delay) {
|
||||
final Message message = progressViewsUpdateHandler.obtainMessage(CMD_REFRESH_PROGRESS_VIEWS);
|
||||
progressViewsUpdateHandler.removeMessages(CMD_REFRESH_PROGRESS_VIEWS);
|
||||
progressViewsUpdateHandler.sendMessageDelayed(message, delay);
|
||||
}
|
||||
|
||||
private long refreshProgressViews() {
|
||||
final int totalMillis = MusicPlayerRemote.getSongDurationMillis();
|
||||
final int progressMillis = MusicPlayerRemote.getSongProgressMillis();
|
||||
|
||||
seekBar.setMax(totalMillis);
|
||||
seekBar.setProgress(progressMillis);
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progressMillis));
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(totalMillis));
|
||||
|
||||
if (!MusicPlayerRemote.isPlaying()) {
|
||||
return DEFAULT_PROGRESS_VIEW_REFRESH_INTERVAL;
|
||||
}
|
||||
|
||||
// calculate the number of milliseconds until the next full second,
|
||||
// so
|
||||
// the counter can be updated at just the right time
|
||||
final long remainingMillis = 1000 - progressMillis % 1000;
|
||||
if (remainingMillis < 20) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
return remainingMillis;
|
||||
}
|
||||
|
||||
private static class MusicProgressViewsUpdateHandler extends Handler {
|
||||
private WeakReference<AbsSlidingMusicPanelActivity> activityReference;
|
||||
|
||||
public MusicProgressViewsUpdateHandler(final AbsSlidingMusicPanelActivity activity) {
|
||||
super();
|
||||
activityReference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
if (msg.what == CMD_REFRESH_PROGRESS_VIEWS) {
|
||||
activityReference.get().queueNextRefresh(activityReference.get().refreshProgressViews());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO use this for the custom player menu
|
||||
// @Override
|
||||
// public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
// getMenuInflater().inflate(R.menu.menu_player, menu);
|
||||
// boolean isFavorite = MusicUtil.isFavorite(this, song);
|
||||
// menu.findItem(R.id.action_toggle_favorite)
|
||||
// .setIcon(isFavorite ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_favorite_outline_white_24dp)
|
||||
// .setTitle(isFavorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
// int id = item.getItemId();
|
||||
// switch (id) {
|
||||
// case R.id.action_sleep_timer:
|
||||
// new SleepTimerDialog().show(getSupportFragmentManager(), "SET_SLEEP_TIMER");
|
||||
// return true;
|
||||
// case R.id.action_toggle_favorite:
|
||||
// MusicUtil.toggleFavorite(this, song);
|
||||
// if (MusicUtil.isFavorite(this, song)) {
|
||||
// animateSetFavorite();
|
||||
// }
|
||||
// invalidateOptionsMenu();
|
||||
// return true;
|
||||
// case R.id.action_share:
|
||||
// SongShareDialog.create(song).show(getSupportFragmentManager(), "SHARE_SONG");
|
||||
// return true;
|
||||
// case R.id.action_equalizer:
|
||||
// NavigationUtil.openEqualizer(this);
|
||||
// return true;
|
||||
// case R.id.action_shuffle_all:
|
||||
// MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(this), true);
|
||||
// return true;
|
||||
// case R.id.action_add_to_playlist:
|
||||
// AddToPlaylistDialog.create(song).show(getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||
// return true;
|
||||
// case android.R.id.home:
|
||||
// super.onBackPressed();
|
||||
// return true;
|
||||
// case R.id.action_playing_queue:
|
||||
// NavigationUtil.openPlayingQueueDialog(this);
|
||||
// return true;
|
||||
// case R.id.action_tag_editor:
|
||||
// Intent intent = new Intent(this, SongTagEditorActivity.class);
|
||||
// intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
|
||||
// startActivity(intent);
|
||||
// return true;
|
||||
// case R.id.action_details:
|
||||
// SongDetailDialog.create(song).show(getSupportFragmentManager(), "SONG_DETAIL");
|
||||
// return true;
|
||||
// case R.id.action_go_to_album:
|
||||
// NavigationUtil.goToAlbum(this, song.albumId, addPlayPauseFabToSharedViews(null));
|
||||
// return true;
|
||||
// case R.id.action_go_to_artist:
|
||||
// NavigationUtil.goToArtist(this, song.artistId, addPlayPauseFabToSharedViews(null));
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return super.onOptionsItemSelected(item);
|
||||
// }
|
||||
//
|
||||
// private void animateSetFavorite() {
|
||||
// favoriteIcon.clearAnimation();
|
||||
//
|
||||
// favoriteIcon.setAlpha(0f);
|
||||
// favoriteIcon.setScaleX(0f);
|
||||
// favoriteIcon.setScaleY(0f);
|
||||
// favoriteIcon.setVisibility(View.VISIBLE);
|
||||
// favoriteIcon.setPivotX(favoriteIcon.getWidth() / 2);
|
||||
// favoriteIcon.setPivotY(favoriteIcon.getHeight() / 2);
|
||||
//
|
||||
// favoriteIcon.animate()
|
||||
// .setDuration(600)
|
||||
// .setInterpolator(new OvershootInterpolator())
|
||||
// .scaleX(1f)
|
||||
// .scaleY(1f)
|
||||
// .alpha(1f)
|
||||
// .setListener(new SimpleAnimatorListener() {
|
||||
// @Override
|
||||
// public void onAnimationCancel(Animator animation) {
|
||||
// favoriteIcon.setVisibility(View.INVISIBLE);
|
||||
// }
|
||||
// })
|
||||
// .withEndAction(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// favoriteIcon.animate()
|
||||
// .setDuration(300)
|
||||
// .setInterpolator(new DecelerateInterpolator())
|
||||
// .alpha(0f)
|
||||
// .start();
|
||||
// }
|
||||
// })
|
||||
// .start();
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.kabouzeid.gramophone.ui.activities.base;
|
|||
import android.app.ActivityManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
|
@ -72,7 +73,7 @@ public abstract class AbsThemeActivity extends AppCompatActivity implements KabV
|
|||
darkTheme != (PreferenceUtil.getInstance(this).getGeneralTheme() == R.style.Theme_MaterialMusic);
|
||||
}
|
||||
|
||||
protected void notifyTaskColorChange(int color) {
|
||||
protected void notifyTaskColorChange(@ColorInt int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Sets color of entry in the system recents page
|
||||
if (taskDescription == null || taskDescription.getPrimaryColor() != color) {
|
||||
|
|
@ -108,18 +109,29 @@ public abstract class AbsThemeActivity extends AppCompatActivity implements KabV
|
|||
Util.setStatusBarTranslucent(getWindow());
|
||||
}
|
||||
|
||||
protected final void setNavigationBarColor(int color) {
|
||||
protected final void setNavigationBarColor(@ColorInt int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
getWindow().setNavigationBarColor(ColorUtil.shiftColorDown(color));
|
||||
}
|
||||
|
||||
protected final void setStatusBarColor(int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
getWindow().setStatusBarColor(ColorUtil.shiftColorDown(color));
|
||||
// also do this on Lollipop in case the user modified the statusbar height
|
||||
/**
|
||||
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop.
|
||||
* On Lollipop if no such view is found it will set the statusbar color using the native method.
|
||||
*
|
||||
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
||||
*/
|
||||
protected final void setStatusBarColor(@ColorInt int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) statusBar.setBackgroundColor(color);
|
||||
if (statusBar != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
statusBar.setBackgroundColor(ColorUtil.shiftColorDown(color));
|
||||
} else {
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(ColorUtil.shiftColorDown(color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import com.afollestad.materialdialogs.ThemeSingleton;
|
|||
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
|
@ -116,7 +116,7 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
|||
observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||
}
|
||||
|
||||
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||
private final SimpleObservableScrollViewCallbacks observableScrollViewCallbacks = new SimpleObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
float alpha;
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ public class ColorUtil {
|
|||
return color | 0xFF000000;
|
||||
}
|
||||
|
||||
public static int getColorWithAlpha(float alpha, int baseColor) {
|
||||
public static int getColorWithAlpha(float alpha, @ColorInt int baseColor) {
|
||||
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24;
|
||||
int rgb = 0x00ffffff & baseColor;
|
||||
return a + rgb;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResourceType")
|
||||
public static int shiftColorDown(int color) {
|
||||
public static int shiftColorDown(@ColorInt int color) {
|
||||
int alpha = Color.alpha(color);
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color, hsv);
|
||||
|
|
@ -51,7 +51,7 @@ public class ColorUtil {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static ColorStateList getEmptyColorStateList(int color) {
|
||||
public static ColorStateList getEmptyColorStateList(@ColorInt int color) {
|
||||
return new ColorStateList(
|
||||
new int[][]{
|
||||
new int[]{}
|
||||
|
|
@ -60,11 +60,15 @@ public class ColorUtil {
|
|||
);
|
||||
}
|
||||
|
||||
public static boolean useDarkTextColorOnBackground(int backgroundColor) {
|
||||
public static boolean useDarkTextColorOnBackground(@ColorInt int backgroundColor) {
|
||||
return (Color.red(backgroundColor) * 0.299 + Color.green(backgroundColor) * 0.587 + Color.blue(backgroundColor) * 0.114) > (255 / 2);
|
||||
}
|
||||
|
||||
public static int getTextColorForBackground(int backgroundColor) {
|
||||
return useDarkTextColorOnBackground(backgroundColor) ? Color.BLACK : Color.WHITE;
|
||||
public static int getPrimaryTextColorForBackground(final Context context, @ColorInt int backgroundColor) {
|
||||
return useDarkTextColorOnBackground(backgroundColor) ? context.getResources().getColor(R.color.primary_text_default_material_light) : context.getResources().getColor(R.color.primary_text_default_material_dark);
|
||||
}
|
||||
|
||||
public static int getSecondaryTextColorForBackground(final Context context, @ColorInt int backgroundColor) {
|
||||
return useDarkTextColorOnBackground(backgroundColor) ? context.getResources().getColor(R.color.secondary_text_default_material_light) : context.getResources().getColor(R.color.secondary_text_default_material_dark);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
|||
import com.kabouzeid.gramophone.model.Playlist;
|
||||
import com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.ArtistDetailActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.MusicControllerActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.PlaylistDetailActivity;
|
||||
|
||||
/**
|
||||
|
|
@ -85,30 +84,6 @@ public class NavigationUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static void openCurrentPlayingIfPossible(final Activity activity, @Nullable final Pair[] sharedViews) {
|
||||
if (activity instanceof MusicControllerActivity) {
|
||||
activity.onBackPressed();
|
||||
return;
|
||||
}
|
||||
if (MusicPlayerRemote.getPosition() != -1) {
|
||||
if ((activity instanceof KabViewsDisableAble && ((KabViewsDisableAble) activity).areViewsEnabled()) || !(activity instanceof KabViewsDisableAble)) {
|
||||
if (activity instanceof KabViewsDisableAble)
|
||||
((KabViewsDisableAble) activity).disableViews();
|
||||
Intent intent = new Intent(activity, MusicControllerActivity.class);
|
||||
if (sharedViews != null) {
|
||||
@SuppressWarnings("unchecked") ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
|
||||
sharedViews
|
||||
);
|
||||
ActivityCompat.startActivity(activity, intent, optionsCompat.toBundle());
|
||||
} else {
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(activity, activity.getResources().getString(R.string.playing_queue_empty), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void openPlayingQueueDialog(@NonNull final AppCompatActivity activity) {
|
||||
PlayingQueueDialog dialog = PlayingQueueDialog.create();
|
||||
if (dialog != null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue