Merge remote-tracking branch 'origin/master'
# Conflicts: # app/build.gradle
|
|
@ -1,14 +1,17 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
maven { url 'https://maven.fabric.io/public' }
|
||||||
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'io.fabric.tools:gradle:1.18.0'
|
classpath 'io.fabric.tools:gradle:1.18.0'
|
||||||
|
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'io.fabric'
|
apply plugin: 'io.fabric'
|
||||||
|
apply plugin: 'com.jakewharton.hugo'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
maven { url 'https://maven.fabric.io/public' }
|
||||||
|
|
@ -18,14 +21,14 @@ repositories {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 22
|
compileSdkVersion 22
|
||||||
buildToolsVersion "22.0.1"
|
buildToolsVersion "23.0.0 rc1"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.kabouzeid.gramophone"
|
applicationId "com.kabouzeid.gramophone"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
versionCode 24
|
versionCode 29
|
||||||
versionName "0.9.9.4b"
|
versionName "0.9.13b DEV-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|
@ -52,12 +55,13 @@ dependencies {
|
||||||
transitive = true;
|
transitive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
compile 'com.android.support:appcompat-v7:22.1.1@aar'
|
compile 'com.android.support:appcompat-v7:22.2.0@aar'
|
||||||
compile 'com.android.support:recyclerview-v7:22.1.1@aar'
|
compile 'com.android.support:recyclerview-v7:22.2.0@aar'
|
||||||
compile 'com.android.support:gridlayout-v7:22.1.1@aar'
|
compile 'com.android.support:gridlayout-v7:22.2.0@aar'
|
||||||
compile 'com.android.support:palette-v7:22.1.1@aar'
|
compile 'com.android.support:palette-v7:22.2.0@aar'
|
||||||
compile 'com.android.support:support-v13:22.1.1@aar'
|
compile 'com.android.support:support-v13:22.2.0@aar'
|
||||||
compile 'com.android.support:cardview-v7:22.1.1@aar'
|
compile 'com.android.support:cardview-v7:22.2.0@aar'
|
||||||
|
compile 'com.android.support:design:22.2.0@aar'
|
||||||
|
|
||||||
compile 'com.github.ksoichiro:android-observablescrollview:1.5.1'
|
compile 'com.github.ksoichiro:android-observablescrollview:1.5.1'
|
||||||
compile 'asia.ivity.android:drag-sort-listview:1.0'
|
compile 'asia.ivity.android:drag-sort-listview:1.0'
|
||||||
|
|
@ -69,8 +73,7 @@ dependencies {
|
||||||
compile 'de.hdodenhof:circleimageview:1.3.0'
|
compile 'de.hdodenhof:circleimageview:1.3.0'
|
||||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
|
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
|
||||||
|
|
||||||
compile 'com.afollestad:material-dialogs:0.7.5.0'
|
compile 'com.afollestad:material-dialogs:0.7.4.2'
|
||||||
compile 'com.jpardogo.materialtabstrip:library:1.0.9'
|
compile 'com.afollestad:material-cab:0.1.2'
|
||||||
compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
|
compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
|
||||||
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.kabouzeid.gramophone.adapter;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<VH> implements MaterialCab.Callback {
|
||||||
|
private final CabHolder cabHolder;
|
||||||
|
private MaterialCab cab;
|
||||||
|
private ArrayList<I> checked;
|
||||||
|
private int menuRes;
|
||||||
|
|
||||||
|
public AbsMultiSelectAdapter(@Nullable CabHolder cabHolder, int menuRes) {
|
||||||
|
this.cabHolder = cabHolder;
|
||||||
|
checked = new ArrayList<>();
|
||||||
|
this.menuRes = menuRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void toggleChecked(final int position) {
|
||||||
|
if (cabHolder != null) {
|
||||||
|
openCabIfNecessary();
|
||||||
|
|
||||||
|
I identifier = getIdentifier(position);
|
||||||
|
if (!checked.remove(identifier)) checked.add(identifier);
|
||||||
|
notifyItemChanged(position);
|
||||||
|
|
||||||
|
final int size = checked.size();
|
||||||
|
if (size <= 0) cab.finish();
|
||||||
|
else if (size == 1) cab.setTitle(checked.get(0).toString());
|
||||||
|
else if (size > 1) cab.setTitle(String.valueOf(size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openCabIfNecessary() {
|
||||||
|
if (cabHolder != null) {
|
||||||
|
if (cab == null || !cab.isActive()) {
|
||||||
|
cab = cabHolder.openCab(menuRes, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uncheckAll() {
|
||||||
|
checked.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isChecked(I identifier) {
|
||||||
|
return checked.contains(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isInQuickSelectMode() {
|
||||||
|
return cab != null && cab.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||||
|
onMultipleItemAction(menuItem, new ArrayList<>(checked));
|
||||||
|
cab.finish();
|
||||||
|
uncheckAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabFinished(MaterialCab materialCab) {
|
||||||
|
uncheckAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract I getIdentifier(int position);
|
||||||
|
|
||||||
|
protected abstract void onMultipleItemAction(MenuItem menuItem, ArrayList<I> selection);
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,39 @@
|
||||||
package com.kabouzeid.gramophone.adapter;
|
package com.kabouzeid.gramophone.adapter;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||||
|
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
@ -29,15 +41,16 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
|
public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album> {
|
||||||
|
|
||||||
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
||||||
private final Activity activity;
|
private final AppCompatActivity activity;
|
||||||
private boolean usePalette;
|
private boolean usePalette;
|
||||||
private List<Album> dataSet;
|
private List<Album> dataSet;
|
||||||
|
|
||||||
|
|
@ -53,6 +66,10 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
|
|
||||||
resetColors(holder.title, holder.artist, holder.footer);
|
resetColors(holder.title, holder.artist, holder.footer);
|
||||||
|
|
||||||
|
final boolean isChecked = isChecked(album);
|
||||||
|
holder.view.setActivated(isChecked);
|
||||||
|
holder.checkMark.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
|
||||||
holder.title.setText(album.title);
|
holder.title.setText(album.title);
|
||||||
holder.artist.setText(album.artistName);
|
holder.artist.setText(album.artistName);
|
||||||
|
|
||||||
|
|
@ -67,12 +84,14 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
new SimpleImageLoadingListener() {
|
new SimpleImageLoadingListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
paletteBlackAndWhite(holder.title, holder.artist, holder.footer);
|
if (usePalette)
|
||||||
|
paletteBlackAndWhite(holder.title, holder.artist, holder.footer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||||
applyPalette(loadedImage, holder.title, holder.artist, holder.footer);
|
if (usePalette)
|
||||||
|
applyPalette(loadedImage, holder.title, holder.artist, holder.footer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -83,34 +102,90 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
return dataSet.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Album getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Album> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(getSongList(selection));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Song> getSongList(List<Album> albums) {
|
||||||
|
final ArrayList<Song> songs = new ArrayList<>();
|
||||||
|
for (Album album : albums) {
|
||||||
|
songs.addAll(AlbumSongLoader.getAlbumSongList(activity, album.id));
|
||||||
|
}
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final ImageView albumArt;
|
final ImageView albumArt;
|
||||||
final TextView title;
|
final TextView title;
|
||||||
final TextView artist;
|
final TextView artist;
|
||||||
final View footer;
|
final View footer;
|
||||||
|
final ImageView checkMark;
|
||||||
|
final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
||||||
title = (TextView) itemView.findViewById(R.id.album_title);
|
title = (TextView) itemView.findViewById(R.id.album_title);
|
||||||
artist = (TextView) itemView.findViewById(R.id.album_interpret);
|
artist = (TextView) itemView.findViewById(R.id.album_interpret);
|
||||||
footer = itemView.findViewById(R.id.footer);
|
footer = itemView.findViewById(R.id.footer);
|
||||||
itemView.setOnClickListener(this);
|
checkMark = (ImageView) itemView.findViewById(R.id.check_mark);
|
||||||
|
view.setOnClickListener(this);
|
||||||
|
view.setOnLongClickListener(this);
|
||||||
|
|
||||||
|
// fixes the ripple starts at the right position
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
view.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||||
|
((FrameLayout) view.findViewById(R.id.content)).getForeground().setHotspot(motionEvent.getX(), motionEvent.getY());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Pair[] albumPairs = new Pair[]{
|
if (isInQuickSelectMode()) {
|
||||||
Pair.create(albumArt,
|
toggleChecked(getAdapterPosition());
|
||||||
activity.getResources().getString(R.string.transition_album_cover)
|
} else {
|
||||||
)};
|
Pair[] albumPairs = new Pair[]{
|
||||||
if (activity instanceof AbsFabActivity)
|
Pair.create(albumArt,
|
||||||
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
activity.getResources().getString(R.string.transition_album_cover)
|
||||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).id, albumPairs);
|
)};
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
||||||
|
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).id, albumPairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(getAdapterPosition());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AlbumAdapter(Activity activity) {
|
public AlbumAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_media_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
usePalette = PreferenceUtils.getInstance(activity).coloredAlbumFootersEnabled();
|
usePalette = PreferenceUtils.getInstance(activity).coloredAlbumFootersEnabled();
|
||||||
loadDataSet();
|
loadDataSet();
|
||||||
|
|
@ -128,9 +203,9 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
||||||
if (vibrantSwatch != null) {
|
if (vibrantSwatch != null) {
|
||||||
title.setTextColor(vibrantSwatch.getTitleTextColor());
|
title.setTextColor(Util.getOpaqueColor(vibrantSwatch.getTitleTextColor()));
|
||||||
artist.setTextColor(vibrantSwatch.getTitleTextColor());
|
artist.setTextColor(Util.getOpaqueColor(vibrantSwatch.getTitleTextColor()));
|
||||||
ViewUtil.animateViewColor(footer, DialogUtils.resolveColor(activity, R.attr.default_bar_color), vibrantSwatch.getRgb());
|
ViewUtil.animateViewColor(footer, footer.getDrawingCacheBackgroundColor(), vibrantSwatch.getRgb());
|
||||||
} else {
|
} else {
|
||||||
paletteBlackAndWhite(title, artist, footer);
|
paletteBlackAndWhite(title, artist, footer);
|
||||||
}
|
}
|
||||||
|
|
@ -142,8 +217,8 @@ public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paletteBlackAndWhite(final TextView title, final TextView artist, final View footer) {
|
private void paletteBlackAndWhite(final TextView title, final TextView artist, final View footer) {
|
||||||
title.setTextColor(DialogUtils.resolveColor(activity, R.attr.title_text_color));
|
title.setTextColor(Util.getOpaqueColor(DialogUtils.resolveColor(activity, R.attr.title_text_color)));
|
||||||
artist.setTextColor(DialogUtils.resolveColor(activity, R.attr.caption_text_color));
|
artist.setTextColor(Util.getOpaqueColor(DialogUtils.resolveColor(activity, R.attr.caption_text_color)));
|
||||||
int defaultBarColor = DialogUtils.resolveColor(activity, R.attr.default_bar_color);
|
int defaultBarColor = DialogUtils.resolveColor(activity, R.attr.default_bar_color);
|
||||||
ViewUtil.animateViewColor(footer, defaultBarColor, defaultBarColor);
|
ViewUtil.animateViewColor(footer, defaultBarColor, defaultBarColor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package com.kabouzeid.gramophone.adapter;
|
package com.kabouzeid.gramophone.adapter;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
@ -11,10 +13,16 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistThumbnailUrlLoader;
|
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistThumbnailUrlLoader;
|
||||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||||
|
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Artist;
|
import com.kabouzeid.gramophone.model.Artist;
|
||||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
|
|
@ -22,16 +30,18 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder> {
|
public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist> {
|
||||||
protected final Activity activity;
|
protected final AppCompatActivity activity;
|
||||||
protected List<Artist> dataSet;
|
protected List<Artist> dataSet;
|
||||||
|
|
||||||
public ArtistAdapter(Activity activity) {
|
public ArtistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_media_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
loadDataSet();
|
loadDataSet();
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +63,7 @@ public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder
|
||||||
holder.artistName.setText(artist.name);
|
holder.artistName.setText(artist.name);
|
||||||
holder.artistInfo.setText(MusicUtil.getArtistInfoString(activity, artist));
|
holder.artistInfo.setText(MusicUtil.getArtistInfoString(activity, artist));
|
||||||
holder.artistImage.setImageResource(R.drawable.default_artist_image);
|
holder.artistImage.setImageResource(R.drawable.default_artist_image);
|
||||||
|
holder.view.setActivated(isChecked(artist));
|
||||||
|
|
||||||
LastFMArtistThumbnailUrlLoader.loadArtistThumbnailUrl(activity, artist.name, false, new LastFMArtistThumbnailUrlLoader.ArtistThumbnailUrlLoaderCallback() {
|
LastFMArtistThumbnailUrlLoader.loadArtistThumbnailUrl(activity, artist.name, false, new LastFMArtistThumbnailUrlLoader.ArtistThumbnailUrlLoaderCallback() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -73,28 +84,69 @@ public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder
|
||||||
return dataSet.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Artist getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Artist> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(getSongList(selection));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Song> getSongList(List<Artist> artists) {
|
||||||
|
final ArrayList<Song> songs = new ArrayList<>();
|
||||||
|
for (Artist artist : artists) {
|
||||||
|
songs.addAll(ArtistSongLoader.getArtistSongList(activity, artist.id));
|
||||||
|
}
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final TextView artistName;
|
final TextView artistName;
|
||||||
final TextView artistInfo;
|
final TextView artistInfo;
|
||||||
final ImageView artistImage;
|
final ImageView artistImage;
|
||||||
|
final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
artistName = (TextView) itemView.findViewById(R.id.artist_name);
|
artistName = (TextView) itemView.findViewById(R.id.artist_name);
|
||||||
artistInfo = (TextView) itemView.findViewById(R.id.artist_info);
|
artistInfo = (TextView) itemView.findViewById(R.id.artist_info);
|
||||||
artistImage = (ImageView) itemView.findViewById(R.id.artist_image);
|
artistImage = (ImageView) itemView.findViewById(R.id.artist_image);
|
||||||
itemView.setOnClickListener(this);
|
view.setOnClickListener(this);
|
||||||
|
view.setOnLongClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Pair[] artistPairs = new Pair[]{
|
if (isInQuickSelectMode()) {
|
||||||
Pair.create(artistImage,
|
toggleChecked(getAdapterPosition());
|
||||||
activity.getResources().getString(R.string.transition_artist_image)
|
} else {
|
||||||
)};
|
Pair[] artistPairs = new Pair[]{
|
||||||
if (activity instanceof AbsFabActivity)
|
Pair.create(artistImage,
|
||||||
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
|
activity.getResources().getString(R.string.transition_artist_image)
|
||||||
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).id, artistPairs);
|
)};
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
artistPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(artistPairs);
|
||||||
|
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).id, artistPairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(getAdapterPosition());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,59 @@
|
||||||
package com.kabouzeid.gramophone.adapter;
|
package com.kabouzeid.gramophone.adapter;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
|
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class ArtistAlbumAdapter extends RecyclerView.Adapter<ArtistAlbumAdapter.ViewHolder> {
|
public class ArtistAlbumAdapter extends AbsMultiSelectAdapter<ArtistAlbumAdapter.ViewHolder, Album> {
|
||||||
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
||||||
|
|
||||||
private static final int TYPE_FIRST = 1;
|
private static final int TYPE_FIRST = 1;
|
||||||
private static final int TYPE_MIDDLE = 2;
|
private static final int TYPE_MIDDLE = 2;
|
||||||
private static final int TYPE_LAST = 3;
|
private static final int TYPE_LAST = 3;
|
||||||
|
|
||||||
private final Activity activity;
|
private final AppCompatActivity activity;
|
||||||
private final List<Album> dataSet;
|
private ArrayList<Album> dataSet;
|
||||||
private final int listMargin;
|
private final int listMargin;
|
||||||
|
|
||||||
|
public ArtistAlbumAdapter(AppCompatActivity activity, ArrayList<Album> objects, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_media_selection);
|
||||||
|
this.activity = activity;
|
||||||
|
dataSet = objects;
|
||||||
|
listMargin = activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDataSet(ArrayList<Album> objects) {
|
||||||
|
dataSet = objects;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(activity).inflate(R.layout.item_grid_artist_album, parent, false);
|
View view = LayoutInflater.from(activity).inflate(R.layout.item_grid_artist_album, parent, false);
|
||||||
|
|
@ -61,6 +82,7 @@ public class ArtistAlbumAdapter extends RecyclerView.Adapter<ArtistAlbumAdapter.
|
||||||
|
|
||||||
holder.title.setText(album.title);
|
holder.title.setText(album.title);
|
||||||
holder.year.setText(String.valueOf(album.year));
|
holder.year.setText(String.valueOf(album.year));
|
||||||
|
holder.view.setActivated(isChecked(album));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -77,34 +99,69 @@ public class ArtistAlbumAdapter extends RecyclerView.Adapter<ArtistAlbumAdapter.
|
||||||
} else return TYPE_MIDDLE;
|
} else return TYPE_MIDDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Album getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Album> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(getSongList(selection));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Song> getSongList(List<Album> albums) {
|
||||||
|
final ArrayList<Song> songs = new ArrayList<>();
|
||||||
|
for (Album album : albums) {
|
||||||
|
songs.addAll(AlbumSongLoader.getAlbumSongList(activity, album.id));
|
||||||
|
}
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final ImageView albumArt;
|
final ImageView albumArt;
|
||||||
final TextView title;
|
final TextView title;
|
||||||
final TextView year;
|
final TextView year;
|
||||||
|
final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
||||||
title = (TextView) itemView.findViewById(R.id.album_title);
|
title = (TextView) itemView.findViewById(R.id.album_title);
|
||||||
year = (TextView) itemView.findViewById(R.id.album_year);
|
year = (TextView) itemView.findViewById(R.id.album_year);
|
||||||
itemView.setOnClickListener(this);
|
view.setOnClickListener(this);
|
||||||
|
view.setOnLongClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Pair[] albumPairs = new Pair[]{
|
if (isInQuickSelectMode()) {
|
||||||
Pair.create(albumArt,
|
toggleChecked(getAdapterPosition());
|
||||||
activity.getResources().getString(R.string.transition_album_cover)
|
} else {
|
||||||
)};
|
Pair[] albumPairs = new Pair[]{
|
||||||
if (activity instanceof AbsFabActivity)
|
Pair.create(albumArt,
|
||||||
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
activity.getResources().getString(R.string.transition_album_cover)
|
||||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).id, albumPairs);
|
)};
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
||||||
|
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).id, albumPairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(getAdapterPosition());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArtistAlbumAdapter(Activity activity, List<Album> objects) {
|
|
||||||
this.activity = activity;
|
|
||||||
dataSet = objects;
|
|
||||||
listMargin = activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.adapter;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
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.ColorChooserDialog;
|
|
||||||
import com.kabouzeid.gramophone.model.NavigationDrawerItem;
|
|
||||||
import com.kabouzeid.gramophone.ui.fragments.NavigationDrawerFragment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Aidan Follestad (afollestad)
|
|
||||||
*/
|
|
||||||
public class NavigationDrawerItemAdapter extends RecyclerView.Adapter<NavigationDrawerItemAdapter.ShortcutViewHolder> implements View.OnClickListener {
|
|
||||||
|
|
||||||
// per the Material design guidelines
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
private final int ALPHA_ACTIVATED = 255;
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
private final int ALPHA_ICON = 138;
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
private final int ALPHA_TEXT = 222;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
int index = (Integer) v.getTag();
|
|
||||||
if (mCallback != null)
|
|
||||||
mCallback.onItemSelected(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ShortcutViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
public ShortcutViewHolder(View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
divider = itemView.findViewById(R.id.divider);
|
|
||||||
container = itemView.findViewById(R.id.container);
|
|
||||||
title = (TextView) itemView.findViewById(R.id.title);
|
|
||||||
icon = (ImageView) itemView.findViewById(R.id.icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
final TextView title;
|
|
||||||
final ImageView icon;
|
|
||||||
final View divider;
|
|
||||||
final View container;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int currentChecked = -1;
|
|
||||||
private int navIconColor;
|
|
||||||
private final ArrayList<NavigationDrawerItem> mItems;
|
|
||||||
private final Callback mCallback;
|
|
||||||
|
|
||||||
public interface Callback {
|
|
||||||
void onItemSelected(int index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NavigationDrawerItemAdapter(Context context, ArrayList<NavigationDrawerItem> objects, Callback callback) {
|
|
||||||
navIconColor = DialogUtils.resolveColor(context, R.attr.nav_drawer_icon_color);
|
|
||||||
if (DialogUtils.isColorDark(navIconColor))
|
|
||||||
navIconColor = ColorChooserDialog.shiftColorUp(navIconColor);
|
|
||||||
mItems = objects;
|
|
||||||
mCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChecked(int position) {
|
|
||||||
// int oldPosition = currentChecked;
|
|
||||||
currentChecked = position;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ShortcutViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
||||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_navigation_drawer, parent, false);
|
|
||||||
return new ShortcutViewHolder(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(ShortcutViewHolder holder, int position) {
|
|
||||||
NavigationDrawerItem item = mItems.get(position);
|
|
||||||
|
|
||||||
holder.title.setText(item.title);
|
|
||||||
holder.icon.setImageResource(item.imageRes);
|
|
||||||
holder.divider.setVisibility(position == NavigationDrawerFragment.SETTINGS_INDEX ?
|
|
||||||
View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
final boolean selected = position == currentChecked;
|
|
||||||
final int iconColor = selected ? ThemeSingleton.get().positiveColor : navIconColor;
|
|
||||||
final int textColor = selected ? ThemeSingleton.get().positiveColor : navIconColor;
|
|
||||||
|
|
||||||
holder.title.setTextColor(textColor);
|
|
||||||
holder.title.setAlpha(selected ? ALPHA_ACTIVATED : ALPHA_TEXT);
|
|
||||||
holder.icon.setColorFilter(iconColor, PorterDuff.Mode.SRC_ATOP);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
holder.icon.setImageAlpha(selected ? ALPHA_ACTIVATED : ALPHA_ICON);
|
|
||||||
} else {
|
|
||||||
// noinspection deprecation
|
|
||||||
holder.icon.setAlpha(selected ? ALPHA_ACTIVATED : ALPHA_ICON);
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.container.setActivated(selected);
|
|
||||||
holder.container.setTag(position);
|
|
||||||
holder.container.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return mItems.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter;
|
package com.kabouzeid.gramophone.adapter;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
@ -10,25 +11,36 @@ import android.view.ViewGroup;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeletePlaylistDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||||
|
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
|
||||||
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHolder> {
|
public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist> {
|
||||||
|
|
||||||
public static final String TAG = PlaylistAdapter.class.getSimpleName();
|
public static final String TAG = PlaylistAdapter.class.getSimpleName();
|
||||||
protected final AppCompatActivity activity;
|
protected final AppCompatActivity activity;
|
||||||
protected List<Playlist> dataSet;
|
protected List<Playlist> dataSet;
|
||||||
|
|
||||||
public PlaylistAdapter(AppCompatActivity activity) {
|
public PlaylistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_playlists_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
loadDataSet();
|
loadDataSet();
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +57,9 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||||
holder.playlistName.setText(dataSet.get(position).name);
|
final Playlist playlist = dataSet.get(position);
|
||||||
|
holder.playlistName.setText(playlist.name);
|
||||||
|
holder.view.setActivated(isChecked(playlist));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -53,15 +67,46 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
|
||||||
return dataSet.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Playlist getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Playlist> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_playlist:
|
||||||
|
DeletePlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "DELETE_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(getSongList(selection)).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(getSongList(selection));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Song> getSongList(List<Playlist> playlists) {
|
||||||
|
final ArrayList<Song> songs = new ArrayList<>();
|
||||||
|
for (Playlist playlist : playlists) {
|
||||||
|
songs.addAll(PlaylistSongLoader.getPlaylistSongList(activity, playlist.id));
|
||||||
|
}
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
public final TextView playlistName;
|
public final TextView playlistName;
|
||||||
private final View menu;
|
private final View menu;
|
||||||
|
private final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
playlistName = (TextView) itemView.findViewById(R.id.playlist_name);
|
playlistName = (TextView) itemView.findViewById(R.id.playlist_name);
|
||||||
menu = itemView.findViewById(R.id.menu);
|
menu = itemView.findViewById(R.id.menu);
|
||||||
itemView.setOnClickListener(this);
|
view.setOnClickListener(this);
|
||||||
|
view.setOnLongClickListener(this);
|
||||||
menu.setOnClickListener(new View.OnClickListener() {
|
menu.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
|
@ -81,10 +126,43 @@ public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.ViewHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Pair[] sharedViews = null;
|
if (isInQuickSelectMode()) {
|
||||||
if (activity instanceof AbsFabActivity)
|
toggleChecked(getAdapterPosition());
|
||||||
sharedViews = ((AbsFabActivity) activity).getSharedViewsWithFab(null);
|
} else {
|
||||||
NavigationUtil.goToPlaylist(activity, dataSet.get(getAdapterPosition()).id, sharedViews);
|
Pair[] sharedViews = null;
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
sharedViews = ((AbsFabActivity) activity).getSharedViewsWithFab(null);
|
||||||
|
NavigationUtil.goToPlaylist(activity, dataSet.get(getAdapterPosition()).id, sharedViews);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(getAdapterPosition());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
|
||||||
|
super.onDetachedFromRecyclerView(recyclerView);
|
||||||
|
App.bus.unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
||||||
|
super.onAttachedToRecyclerView(recyclerView);
|
||||||
|
App.bus.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case DataBaseChangedEvent.PLAYLISTS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||||
|
loadDataSet();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
|
@ -20,11 +21,13 @@ import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
import com.kabouzeid.gramophone.model.Artist;
|
import com.kabouzeid.gramophone.model.Artist;
|
||||||
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -41,12 +44,14 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
|
|
||||||
private AppCompatActivity activity;
|
private AppCompatActivity activity;
|
||||||
private List results = Collections.emptyList();
|
private List results = Collections.emptyList();
|
||||||
|
private String query;
|
||||||
|
|
||||||
public SearchAdapter(AppCompatActivity activity) {
|
public SearchAdapter(AppCompatActivity activity) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void search(String query) {
|
public void search(String query) {
|
||||||
|
this.query = query;
|
||||||
results = new ArrayList();
|
results = new ArrayList();
|
||||||
if (!query.trim().equals("")) {
|
if (!query.trim().equals("")) {
|
||||||
List songs = SongLoader.getSongs(activity, query);
|
List songs = SongLoader.getSongs(activity, query);
|
||||||
|
|
@ -224,4 +229,26 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
|
||||||
|
super.onDetachedFromRecyclerView(recyclerView);
|
||||||
|
App.bus.unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
||||||
|
super.onAttachedToRecyclerView(recyclerView);
|
||||||
|
App.bus.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case DataBaseChangedEvent.ALBUMS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||||
|
search(query);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter.songadapter;
|
package com.kabouzeid.gramophone.adapter.songadapter;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
@ -11,8 +12,12 @@ import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.adapter.AbsMultiSelectAdapter;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
|
|
||||||
|
|
@ -21,17 +26,23 @@ import java.util.ArrayList;
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.ViewHolder> {
|
public class AlbumSongAdapter extends AbsMultiSelectAdapter<AlbumSongAdapter.ViewHolder, Song> {
|
||||||
|
|
||||||
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
||||||
protected final AppCompatActivity activity;
|
protected final AppCompatActivity activity;
|
||||||
protected final ArrayList<Song> dataSet;
|
protected ArrayList<Song> dataSet;
|
||||||
|
|
||||||
public AlbumSongAdapter(AppCompatActivity activity, ArrayList<Song> objects) {
|
public AlbumSongAdapter(AppCompatActivity activity, ArrayList<Song> objects, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_media_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
dataSet = objects;
|
dataSet = objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateDataSet(ArrayList<Song> objects){
|
||||||
|
dataSet = objects;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(activity).inflate(R.layout.item_list_album_song, parent, false);
|
View view = LayoutInflater.from(activity).inflate(R.layout.item_list_album_song, parent, false);
|
||||||
|
|
@ -47,6 +58,7 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
|
||||||
holder.trackNumber.setText(trackNumberString);
|
holder.trackNumber.setText(trackNumberString);
|
||||||
holder.songTitle.setText(song.title);
|
holder.songTitle.setText(song.title);
|
||||||
holder.artistName.setText(MusicUtil.getReadableDurationString(song.duration));
|
holder.artistName.setText(MusicUtil.getReadableDurationString(song.duration));
|
||||||
|
holder.view.setActivated(isChecked(song));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -54,38 +66,71 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<AlbumSongAdapter.View
|
||||||
return dataSet.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Song getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Song> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(selection).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(selection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final TextView songTitle;
|
final TextView songTitle;
|
||||||
final TextView trackNumber;
|
final TextView trackNumber;
|
||||||
final TextView artistName;
|
final TextView artistName;
|
||||||
final ImageView overflowButton;
|
final ImageView overflowButton;
|
||||||
|
final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
songTitle = (TextView) itemView.findViewById(R.id.song_title);
|
songTitle = (TextView) itemView.findViewById(R.id.song_title);
|
||||||
trackNumber = (TextView) itemView.findViewById(R.id.track_number);
|
trackNumber = (TextView) itemView.findViewById(R.id.track_number);
|
||||||
artistName = (TextView) itemView.findViewById(R.id.song_info);
|
artistName = (TextView) itemView.findViewById(R.id.song_info);
|
||||||
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||||
overflowButton.setOnClickListener(this);
|
view.setOnClickListener(this);
|
||||||
itemView.setOnClickListener(new View.OnClickListener() {
|
view.setOnLongClickListener(this);
|
||||||
|
overflowButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition(), true);
|
PopupMenu popupMenu = new PopupMenu(activity, v);
|
||||||
|
popupMenu.inflate(R.menu.menu_item_song);
|
||||||
|
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popupMenu.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
PopupMenu popupMenu = new PopupMenu(activity, v);
|
if (isInQuickSelectMode()) {
|
||||||
popupMenu.inflate(R.menu.menu_item_song);
|
toggleChecked(getAdapterPosition());
|
||||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
} else {
|
||||||
@Override
|
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition(), true);
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
}
|
||||||
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
|
}
|
||||||
}
|
|
||||||
});
|
@Override
|
||||||
popupMenu.show();
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(getAdapterPosition());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package com.kabouzeid.gramophone.adapter.songadapter;
|
package com.kabouzeid.gramophone.adapter.songadapter;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -11,8 +13,13 @@ import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
|
|
@ -20,22 +27,36 @@ import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class ArtistSongAdapter extends ArrayAdapter<Song> {
|
public class ArtistSongAdapter extends ArrayAdapter<Song> implements MaterialCab.Callback {
|
||||||
|
|
||||||
|
private final CabHolder cabHolder;
|
||||||
|
private MaterialCab cab;
|
||||||
|
private ArrayList<Song> dataSet;
|
||||||
|
private ArrayList<Song> checked;
|
||||||
|
|
||||||
private final AppCompatActivity activity;
|
private final AppCompatActivity activity;
|
||||||
|
|
||||||
public ArtistSongAdapter(AppCompatActivity activity, List<Song> songs) {
|
public ArtistSongAdapter(AppCompatActivity activity, ArrayList<Song> songs, @Nullable CabHolder cabHolder) {
|
||||||
super(activity, R.layout.item_list_song, songs);
|
super(activity, R.layout.item_list_song, songs);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
|
this.cabHolder = cabHolder;
|
||||||
|
checked = new ArrayList<>();
|
||||||
|
dataSet = songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDataSet(ArrayList<Song> objects) {
|
||||||
|
dataSet = objects;
|
||||||
|
clear();
|
||||||
|
addAll(dataSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||||
final Song song = getItem(position);
|
final Song song = getItem(position);
|
||||||
if (convertView == null) {
|
if (convertView == null) {
|
||||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list_artist_song, parent, false);
|
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list_artist_song, parent, false);
|
||||||
|
|
@ -83,6 +104,94 @@ public class ArtistSongAdapter extends ArrayAdapter<Song> {
|
||||||
popupMenu.show();
|
popupMenu.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
convertView.setActivated(isChecked(song));
|
||||||
|
convertView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if (isInQuickSelectMode()) {
|
||||||
|
toggleChecked(song);
|
||||||
|
} else {
|
||||||
|
MusicPlayerRemote.openQueue(dataSet, position, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
convertView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
toggleChecked(song);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onMultipleItemAction(MenuItem menuItem, ArrayList<Song> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(selection).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(selection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void toggleChecked(Song song) {
|
||||||
|
if (cabHolder != null) {
|
||||||
|
openCabIfNecessary();
|
||||||
|
|
||||||
|
if (!checked.remove(song)) checked.add(song);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
|
||||||
|
final int size = checked.size();
|
||||||
|
if (size <= 0) cab.finish();
|
||||||
|
else if (size == 1) cab.setTitle(checked.get(0).toString());
|
||||||
|
else if (size > 1) cab.setTitle(String.valueOf(size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openCabIfNecessary() {
|
||||||
|
if (cabHolder != null) {
|
||||||
|
if (cab == null || !cab.isActive()) {
|
||||||
|
cab = cabHolder.openCab(R.menu.menu_media_selection, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uncheckAll() {
|
||||||
|
checked.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isChecked(Song song) {
|
||||||
|
return checked.contains(song);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isInQuickSelectMode() {
|
||||||
|
return cab != null && cab.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||||
|
onMultipleItemAction(menuItem, new ArrayList<>(checked));
|
||||||
|
cab.finish();
|
||||||
|
uncheckAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabFinished(MaterialCab materialCab) {
|
||||||
|
uncheckAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.kabouzeid.gramophone.adapter.songadapter;
|
package com.kabouzeid.gramophone.adapter.songadapter;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
@ -12,14 +13,17 @@ import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.adapter.AbsMultiSelectAdapter;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteFromPlaylistDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
|
|
@ -29,17 +33,23 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapter.ViewHolder> {
|
public class PlaylistSongAdapter extends AbsMultiSelectAdapter<PlaylistSongAdapter.ViewHolder, PlaylistSong> {
|
||||||
|
|
||||||
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
||||||
protected final AppCompatActivity activity;
|
protected final AppCompatActivity activity;
|
||||||
protected final ArrayList<PlaylistSong> dataSet;
|
protected ArrayList<PlaylistSong> dataSet;
|
||||||
|
|
||||||
public PlaylistSongAdapter(AppCompatActivity activity, ArrayList<PlaylistSong> objects) {
|
public PlaylistSongAdapter(AppCompatActivity activity, ArrayList<PlaylistSong> objects, @Nullable CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_playlists_songs_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
dataSet = objects;
|
dataSet = objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateDataSet(ArrayList<PlaylistSong> objects) {
|
||||||
|
dataSet = objects;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(activity).inflate(R.layout.item_list_song, parent, false);
|
View view = LayoutInflater.from(activity).inflate(R.layout.item_list_song, parent, false);
|
||||||
|
|
@ -48,8 +58,9 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||||
final Song song = dataSet.get(position);
|
final PlaylistSong song = dataSet.get(position);
|
||||||
|
|
||||||
|
holder.view.setActivated(isChecked(song));
|
||||||
holder.songTitle.setText(song.title);
|
holder.songTitle.setText(song.title);
|
||||||
holder.songInfo.setText(song.artistName);
|
holder.songInfo.setText(song.artistName);
|
||||||
ImageLoader.getInstance().displayImage(
|
ImageLoader.getInstance().displayImage(
|
||||||
|
|
@ -68,54 +79,87 @@ public class PlaylistSongAdapter extends RecyclerView.Adapter<PlaylistSongAdapte
|
||||||
return dataSet.size();
|
return dataSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected PlaylistSong getIdentifier(int position) {
|
||||||
|
return dataSet.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<PlaylistSong> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_playlist:
|
||||||
|
DeleteFromPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "DELETE_FROM_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
//noinspection unchecked
|
||||||
|
AddToPlaylistDialog.create((ArrayList<Song>) (List) selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
//noinspection unchecked
|
||||||
|
MusicPlayerRemote.enqueue((ArrayList<Song>) (List) selection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final TextView songTitle;
|
final TextView songTitle;
|
||||||
final TextView songInfo;
|
final TextView songInfo;
|
||||||
final ImageView overflowButton;
|
final ImageView overflowButton;
|
||||||
final ImageView albumArt;
|
final ImageView albumArt;
|
||||||
|
final View view;
|
||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
view = itemView;
|
||||||
songTitle = (TextView) itemView.findViewById(R.id.song_title);
|
songTitle = (TextView) itemView.findViewById(R.id.song_title);
|
||||||
songInfo = (TextView) itemView.findViewById(R.id.song_info);
|
songInfo = (TextView) itemView.findViewById(R.id.song_info);
|
||||||
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
albumArt = (ImageView) itemView.findViewById(R.id.album_art);
|
||||||
|
view.setOnClickListener(this);
|
||||||
|
view.setOnLongClickListener(this);
|
||||||
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||||
overflowButton.setOnClickListener(this);
|
overflowButton.setOnClickListener(new View.OnClickListener() {
|
||||||
itemView.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
//noinspection unchecked
|
PopupMenu popupMenu = new PopupMenu(activity, v);
|
||||||
MusicPlayerRemote.openQueue((ArrayList<Song>) (List) dataSet, getAdapterPosition(), true);
|
popupMenu.inflate(R.menu.menu_item_playlist_song);
|
||||||
|
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_delete_from_playlist:
|
||||||
|
DeleteFromPlaylistDialog.create(dataSet.get(getAdapterPosition())).show(activity.getSupportFragmentManager(), "DELETE_FROM_PLAYLIST");
|
||||||
|
return true;
|
||||||
|
case R.id.action_go_to_album:
|
||||||
|
Pair[] albumPairs = new Pair[]{
|
||||||
|
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
|
||||||
|
};
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
||||||
|
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popupMenu.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
PopupMenu popupMenu = new PopupMenu(activity, v);
|
if (isInQuickSelectMode()) {
|
||||||
popupMenu.inflate(R.menu.menu_item_playlist_song);
|
toggleChecked(getAdapterPosition());
|
||||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
} else {
|
||||||
@Override
|
//noinspection unchecked
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
MusicPlayerRemote.openQueue((ArrayList<Song>) (List) dataSet, getAdapterPosition(), true);
|
||||||
switch (item.getItemId()) {
|
}
|
||||||
case R.id.action_delete_from_playlist:
|
}
|
||||||
int position = getAdapterPosition();
|
|
||||||
PlaylistsUtil.removeFromPlaylist(activity, dataSet.remove(position));
|
@Override
|
||||||
notifyItemRemoved(position);
|
public boolean onLongClick(View view) {
|
||||||
return true;
|
toggleChecked(getAdapterPosition());
|
||||||
case R.id.action_go_to_album:
|
return true;
|
||||||
Pair[] albumPairs = new Pair[]{
|
|
||||||
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
|
|
||||||
};
|
|
||||||
if (activity instanceof AbsFabActivity)
|
|
||||||
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
|
||||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).albumId, albumPairs);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(getAdapterPosition()), item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
popupMenu.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,16 @@ import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.adapter.AbsMultiSelectAdapter;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
|
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
|
@ -32,7 +37,7 @@ import java.util.ArrayList;
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song> implements MaterialCab.Callback {
|
||||||
|
|
||||||
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
public static final String TAG = AlbumSongAdapter.class.getSimpleName();
|
||||||
private static final int SHUFFLE_BUTTON = 0;
|
private static final int SHUFFLE_BUTTON = 0;
|
||||||
|
|
@ -41,7 +46,8 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
||||||
protected final AppCompatActivity activity;
|
protected final AppCompatActivity activity;
|
||||||
protected ArrayList<Song> dataSet;
|
protected ArrayList<Song> dataSet;
|
||||||
|
|
||||||
public SongAdapter(AppCompatActivity activity) {
|
public SongAdapter(AppCompatActivity activity, CabHolder cabHolder) {
|
||||||
|
super(cabHolder, R.menu.menu_media_selection);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
loadDataSet();
|
loadDataSet();
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +83,7 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
||||||
.resetViewBeforeLoading(true)
|
.resetViewBeforeLoading(true)
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
holder.view.setActivated(isChecked(song));
|
||||||
} else {
|
} else {
|
||||||
holder.songTitle.setText(activity.getResources().getString(R.string.shuffle_all).toUpperCase());
|
holder.songTitle.setText(activity.getResources().getString(R.string.shuffle_all).toUpperCase());
|
||||||
holder.songTitle.setTextColor(ThemeSingleton.get().positiveColor);
|
holder.songTitle.setTextColor(ThemeSingleton.get().positiveColor);
|
||||||
|
|
@ -97,7 +104,27 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
||||||
return dataSet.size() + 1;
|
return dataSet.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
@Override
|
||||||
|
protected Song getIdentifier(int position) {
|
||||||
|
return dataSet.get(position - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<Song> selection) {
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.action_delete_from_disk:
|
||||||
|
DeleteSongsDialog.create(selection).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_playlist:
|
||||||
|
AddToPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
|
break;
|
||||||
|
case R.id.action_add_to_current_playing:
|
||||||
|
MusicPlayerRemote.enqueue(selection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
|
||||||
final TextView songTitle;
|
final TextView songTitle;
|
||||||
final TextView songInfo;
|
final TextView songInfo;
|
||||||
final ImageView overflowButton;
|
final ImageView overflowButton;
|
||||||
|
|
@ -115,45 +142,55 @@ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> {
|
||||||
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
overflowButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||||
separator = itemView.findViewById(R.id.separator);
|
separator = itemView.findViewById(R.id.separator);
|
||||||
short_separator = itemView.findViewById(R.id.short_separator);
|
short_separator = itemView.findViewById(R.id.short_separator);
|
||||||
|
view.setOnClickListener(this);
|
||||||
overflowButton.setOnClickListener(this);
|
view.setOnLongClickListener(this);
|
||||||
itemView.setOnClickListener(new View.OnClickListener() {
|
overflowButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View view) {
|
||||||
if (getItemViewType() == SHUFFLE_BUTTON) {
|
PopupMenu popupMenu = new PopupMenu(activity, view);
|
||||||
MusicPlayerRemote.shuffleAllSongs(activity);
|
popupMenu.inflate(R.menu.menu_item_song);
|
||||||
} else {
|
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition() - 1, true);
|
@Override
|
||||||
}
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
final int position = getAdapterPosition() - 1;
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_go_to_album:
|
||||||
|
Pair[] albumPairs = new Pair[]{
|
||||||
|
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
|
||||||
|
};
|
||||||
|
if (activity instanceof AbsFabActivity)
|
||||||
|
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
||||||
|
NavigationUtil.goToAlbum(activity, dataSet.get(position).albumId, albumPairs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(position), item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popupMenu.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
PopupMenu popupMenu = new PopupMenu(activity, v);
|
if (getItemViewType() == SHUFFLE_BUTTON) {
|
||||||
popupMenu.inflate(R.menu.menu_item_song);
|
MusicPlayerRemote.shuffleAllSongs(activity);
|
||||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
} else if (isInQuickSelectMode()) {
|
||||||
@Override
|
toggleChecked(getAdapterPosition());
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
} else {
|
||||||
final int position = getAdapterPosition() - 1;
|
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition() - 1, true);
|
||||||
switch (item.getItemId()) {
|
}
|
||||||
case R.id.action_go_to_album:
|
}
|
||||||
Pair[] albumPairs = new Pair[]{
|
|
||||||
Pair.create(albumArt, activity.getResources().getString(R.string.transition_album_cover))
|
@Override
|
||||||
};
|
public boolean onLongClick(View view) {
|
||||||
if (activity instanceof AbsFabActivity)
|
if (getItemViewType() == SONG)
|
||||||
albumPairs = ((AbsFabActivity) activity).getSharedViewsWithFab(albumPairs);
|
toggleChecked(getAdapterPosition());
|
||||||
NavigationUtil.goToAlbum(activity, dataSet.get(position).albumId, albumPairs);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return MenuItemClickHelper.handleSongMenuClick(activity, dataSet.get(position), item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
popupMenu.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
|
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
|
||||||
super.onDetachedFromRecyclerView(recyclerView);
|
super.onDetachedFromRecyclerView(recyclerView);
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ import android.widget.BaseAdapter;
|
||||||
import android.widget.GridView;
|
import android.widget.GridView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.views.CircleView;
|
import com.kabouzeid.gramophone.views.ColorView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Aidan Follestad (afollestad)
|
* @author Aidan Follestad (afollestad)
|
||||||
|
|
@ -80,7 +79,7 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
|
||||||
if (getArguments().getInt("title", 0) == R.string.primary_color) {
|
if (getArguments().getInt("title", 0) == R.string.primary_color) {
|
||||||
getArguments().putInt("preselect", getResources().getColor(R.color.indigo_500));
|
getArguments().putInt("preselect", getResources().getColor(R.color.indigo_500));
|
||||||
} else if (getArguments().getInt("title", 0) == R.string.accent_color) {
|
} else if (getArguments().getInt("title", 0) == R.string.accent_color) {
|
||||||
getArguments().putInt("preselect", getResources().getColor(R.color.pink_500));
|
getArguments().putInt("preselect", getResources().getColor(R.color.pink_A200));
|
||||||
}
|
}
|
||||||
invalidateGrid();
|
invalidateGrid();
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +94,10 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
|
||||||
mColors[i] = ta.getColor(i, 0);
|
mColors[i] = ta.getColor(i, 0);
|
||||||
ta.recycle();
|
ta.recycle();
|
||||||
mGrid = (GridView) dialog.getCustomView();
|
mGrid = (GridView) dialog.getCustomView();
|
||||||
invalidateGrid();
|
if (mGrid != null) {
|
||||||
|
mGrid.setNumColumns(primary ? 7 : 4);
|
||||||
|
invalidateGrid();
|
||||||
|
}
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,13 +132,12 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
if (convertView == null)
|
if (convertView == null)
|
||||||
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.griditem_color_chooser, parent, false);
|
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.griditem_color_chooser, parent, false);
|
||||||
final boolean dark = ThemeSingleton.get().darkTheme;
|
|
||||||
CircleView child = (CircleView) convertView;
|
final ColorView colorView = (ColorView) convertView;
|
||||||
child.setActivated(getArguments().getInt("preselect") == mColors[position]);
|
colorView.setActivated(getArguments().getInt("preselect") == mColors[position]);
|
||||||
child.setBackgroundColor(mColors[position]);
|
colorView.setBackgroundColor(mColors[position]);
|
||||||
child.setBorderColor(dark ? Color.WHITE : Color.BLACK);
|
colorView.setTag(position);
|
||||||
child.setTag(position);
|
colorView.setOnClickListener(this);
|
||||||
child.setOnClickListener(this);
|
|
||||||
|
|
||||||
Drawable selector = createSelector(mColors[position]);
|
Drawable selector = createSelector(mColors[position]);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
|
@ -147,9 +148,9 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
|
||||||
shiftColorDown(mColors[position])
|
shiftColorDown(mColors[position])
|
||||||
};
|
};
|
||||||
ColorStateList rippleColors = new ColorStateList(states, colors);
|
ColorStateList rippleColors = new ColorStateList(states, colors);
|
||||||
child.setForeground(new RippleDrawable(rippleColors, selector, null));
|
colorView.setForeground(new RippleDrawable(rippleColors, selector, null));
|
||||||
} else {
|
} else {
|
||||||
child.setForeground(selector);
|
colorView.setForeground(selector);
|
||||||
}
|
}
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
|
@ -162,20 +163,14 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int shiftColorDown(int color) {
|
@SuppressWarnings("ResourceType")
|
||||||
|
private static int shiftColorDown(int color) {
|
||||||
float[] hsv = new float[3];
|
float[] hsv = new float[3];
|
||||||
Color.colorToHSV(color, hsv);
|
Color.colorToHSV(color, hsv);
|
||||||
hsv[2] *= 0.9f; // value component
|
hsv[2] *= 0.9f; // value component
|
||||||
return Color.HSVToColor(hsv);
|
return Color.HSVToColor(hsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int shiftColorUp(int color) {
|
|
||||||
float[] hsv = new float[3];
|
|
||||||
Color.colorToHSV(color, hsv);
|
|
||||||
hsv[2] *= 1.1f; // value component
|
|
||||||
return Color.HSVToColor(hsv);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int translucentColor(int color) {
|
private static int translucentColor(int color) {
|
||||||
final float factor = 0.7f;
|
final float factor = 0.7f;
|
||||||
int alpha = Math.round(Color.alpha(color) * factor);
|
int alpha = Math.round(Color.alpha(color) * factor);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.kabouzeid.gramophone.dialogs;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import android.text.Html;
|
||||||
|
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
|
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class DeleteFromPlaylistDialog extends DialogFragment {
|
||||||
|
|
||||||
|
public static DeleteFromPlaylistDialog create(PlaylistSong song) {
|
||||||
|
ArrayList<PlaylistSong> list = new ArrayList<>();
|
||||||
|
list.add(song);
|
||||||
|
return create(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeleteFromPlaylistDialog create(ArrayList<PlaylistSong> songs) {
|
||||||
|
DeleteFromPlaylistDialog dialog = new DeleteFromPlaylistDialog();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putSerializable("songs", songs);
|
||||||
|
dialog.setArguments(args);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
//noinspection unchecked
|
||||||
|
final ArrayList<PlaylistSong> songs = (ArrayList<PlaylistSong>) getArguments().getSerializable("songs");
|
||||||
|
int title;
|
||||||
|
CharSequence content;
|
||||||
|
if (songs.size() > 1) {
|
||||||
|
title = R.string.delete_songs_from_playlist_title;
|
||||||
|
content = Html.fromHtml(getString(R.string.delete_x_songs_from_playlist, songs.size()));
|
||||||
|
} else {
|
||||||
|
title = R.string.delete_song_from_playlist_title;
|
||||||
|
content = Html.fromHtml(getString(R.string.delete_song_x_from_playlist, songs.get(0).title));
|
||||||
|
}
|
||||||
|
return new MaterialDialog.Builder(getActivity())
|
||||||
|
.title(title)
|
||||||
|
.content(content)
|
||||||
|
.positiveText(R.string.delete_action)
|
||||||
|
.negativeText(android.R.string.cancel)
|
||||||
|
.callback(new MaterialDialog.ButtonCallback() {
|
||||||
|
@Override
|
||||||
|
public void onPositive(MaterialDialog dialog) {
|
||||||
|
super.onPositive(dialog);
|
||||||
|
if (getActivity() == null)
|
||||||
|
return;
|
||||||
|
PlaylistsUtil.removeFromPlaylist(getActivity(), songs);
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,17 +8,26 @@ import android.text.Html;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class DeletePlaylistDialog extends DialogFragment {
|
public class DeletePlaylistDialog extends DialogFragment {
|
||||||
|
|
||||||
public static DeletePlaylistDialog create(long playlistId) {
|
public static DeletePlaylistDialog create(Playlist playlist) {
|
||||||
|
ArrayList<Playlist> list = new ArrayList<>();
|
||||||
|
list.add(playlist);
|
||||||
|
return create(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeletePlaylistDialog create(ArrayList<Playlist> playlists) {
|
||||||
DeletePlaylistDialog dialog = new DeletePlaylistDialog();
|
DeletePlaylistDialog dialog = new DeletePlaylistDialog();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putLong("playlist_id", playlistId);
|
args.putSerializable("playlists", playlists);
|
||||||
dialog.setArguments(args);
|
dialog.setArguments(args);
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
@ -26,11 +35,20 @@ public class DeletePlaylistDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
long playlistId = getArguments().getLong("playlist_id");
|
//noinspection unchecked
|
||||||
|
final ArrayList<Playlist> playlists = (ArrayList<Playlist>) getArguments().getSerializable("playlists");
|
||||||
|
int title;
|
||||||
|
CharSequence content;
|
||||||
|
if (playlists.size() > 1) {
|
||||||
|
title = R.string.delete_playlists_title;
|
||||||
|
content = Html.fromHtml(getString(R.string.delete_x_playlists, playlists.size()));
|
||||||
|
} else {
|
||||||
|
title = R.string.delete_playlist_title;
|
||||||
|
content = Html.fromHtml(getString(R.string.delete_playlist_x, playlists.get(0).name));
|
||||||
|
}
|
||||||
return new MaterialDialog.Builder(getActivity())
|
return new MaterialDialog.Builder(getActivity())
|
||||||
.title(R.string.delete_playlist_title)
|
.title(title)
|
||||||
.content(Html.fromHtml(getString(R.string.delete_playlist_x,
|
.content(content)
|
||||||
PlaylistsUtil.getNameForPlaylist(getActivity(), playlistId))))
|
|
||||||
.positiveText(R.string.delete_action)
|
.positiveText(R.string.delete_action)
|
||||||
.negativeText(android.R.string.cancel)
|
.negativeText(android.R.string.cancel)
|
||||||
.callback(new MaterialDialog.ButtonCallback() {
|
.callback(new MaterialDialog.ButtonCallback() {
|
||||||
|
|
@ -39,8 +57,7 @@ public class DeletePlaylistDialog extends DialogFragment {
|
||||||
super.onPositive(dialog);
|
super.onPositive(dialog);
|
||||||
if (getActivity() == null)
|
if (getActivity() == null)
|
||||||
return;
|
return;
|
||||||
long playlistId = getArguments().getLong("playlist_id");
|
PlaylistsUtil.deletePlaylists(getActivity(), playlists);
|
||||||
PlaylistsUtil.deletePlaylist(getActivity(), playlistId);
|
|
||||||
}
|
}
|
||||||
}).build();
|
}).build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ public class DeleteSongsDialog extends DialogFragment {
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
ArrayList<Song> songs = (ArrayList<Song>) getArguments().getSerializable("songs");
|
final ArrayList<Song> songs = (ArrayList<Song>) getArguments().getSerializable("songs");
|
||||||
int title;
|
int title;
|
||||||
CharSequence content;
|
CharSequence content;
|
||||||
if (songs.size() > 1) {
|
if (songs.size() > 1) {
|
||||||
|
|
@ -57,8 +57,6 @@ public class DeleteSongsDialog extends DialogFragment {
|
||||||
super.onPositive(dialog);
|
super.onPositive(dialog);
|
||||||
if (getActivity() == null)
|
if (getActivity() == null)
|
||||||
return;
|
return;
|
||||||
//noinspection unchecked
|
|
||||||
ArrayList<Song> songs = (ArrayList<Song>) getArguments().getSerializable("songs");
|
|
||||||
MusicUtil.deleteTracks(getActivity(), songs);
|
MusicUtil.deleteTracks(getActivity(), songs);
|
||||||
}
|
}
|
||||||
}).build();
|
}).build();
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ public class MenuItemClickHelper {
|
||||||
RenamePlaylistDialog.create(playlist.id).show(activity.getSupportFragmentManager(), "RENAME_PLAYLIST");
|
RenamePlaylistDialog.create(playlist.id).show(activity.getSupportFragmentManager(), "RENAME_PLAYLIST");
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_delete_playlist:
|
case R.id.action_delete_playlist:
|
||||||
DeletePlaylistDialog.create(playlist.id).show(activity.getSupportFragmentManager(), "DELETE_PLAYLIST");
|
DeletePlaylistDialog.create(playlist).show(activity.getSupportFragmentManager(), "DELETE_PLAYLIST");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import com.kabouzeid.gramophone.service.MusicService;
|
||||||
import com.kabouzeid.gramophone.util.InternalStorageUtil;
|
import com.kabouzeid.gramophone.util.InternalStorageUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -251,6 +252,14 @@ public class MusicPlayerRemote {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void enqueue(List<Song> songs) {
|
||||||
|
if (musicService != null) {
|
||||||
|
musicService.addSongs(songs);
|
||||||
|
final String toast = songs.size() == 1 ? musicService.getResources().getString(R.string.added_title_to_playing_queue) : musicService.getResources().getString(R.string.added_x_titles_to_playing_queue, songs.size());
|
||||||
|
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void removeFromQueue(Song song) {
|
public static void removeFromQueue(Song song) {
|
||||||
if (musicService != null) {
|
if (musicService != null) {
|
||||||
musicService.removeSong(song);
|
musicService.removeSong(song);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.kabouzeid.gramophone.helper.bitmapblur;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
interface BlurProcess {
|
||||||
|
/**
|
||||||
|
* Process the given image, blurring by the supplied radius.
|
||||||
|
* If radius is 0, this will return original
|
||||||
|
*
|
||||||
|
* @param original the bitmap to be blurred
|
||||||
|
* @param radius the radius in pixels to blur the image
|
||||||
|
* @return the blurred version of the image.
|
||||||
|
*/
|
||||||
|
Bitmap blur(Bitmap original, float radius);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,329 @@
|
||||||
|
package com.kabouzeid.gramophone.helper.bitmapblur;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blur using Java code.
|
||||||
|
* <p/>
|
||||||
|
* This is a compromise between Gaussian Blur and Box blur
|
||||||
|
* It creates much better looking blurs than Box Blur, but is
|
||||||
|
* 7x faster than my Gaussian Blur implementation.
|
||||||
|
* <p/>
|
||||||
|
* I called it Stack Blur because this describes best how this
|
||||||
|
* filter works internally: it creates a kind of moving stack
|
||||||
|
* of colors whilst scanning through the image. Thereby it
|
||||||
|
* just has to add one new block of color to the right side
|
||||||
|
* of the stack and remove the leftmost color. The remaining
|
||||||
|
* colors on the topmost layer of the stack are either added on
|
||||||
|
* or reduced by one, depending on if they are on the right or
|
||||||
|
* on the left side of the stack.
|
||||||
|
*
|
||||||
|
* @author Enrique López Mañas <eenriquelopez@gmail.com>
|
||||||
|
* http://www.neo-tech.es
|
||||||
|
* <p/>
|
||||||
|
* Author of the original algorithm: Mario Klingemann <mario.quasimondo.com>
|
||||||
|
* <p/>
|
||||||
|
* Based heavily on http://vitiy.info/Code/stackblur.cpp
|
||||||
|
* See http://vitiy.info/stackblur-algorithm-multi-threaded-blur-for-cpp/
|
||||||
|
* @copyright: Enrique López Mañas
|
||||||
|
* @license: Apache License 2.0
|
||||||
|
*/
|
||||||
|
class JavaBlurProcess implements BlurProcess {
|
||||||
|
|
||||||
|
private static final short[] stackblur_mul = {
|
||||||
|
512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512,
|
||||||
|
454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512,
|
||||||
|
482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456,
|
||||||
|
437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512,
|
||||||
|
497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328,
|
||||||
|
320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456,
|
||||||
|
446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335,
|
||||||
|
329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512,
|
||||||
|
505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405,
|
||||||
|
399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328,
|
||||||
|
324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271,
|
||||||
|
268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456,
|
||||||
|
451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388,
|
||||||
|
385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335,
|
||||||
|
332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292,
|
||||||
|
289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final byte[] stackblur_shr = {
|
||||||
|
9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
|
||||||
|
17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
|
||||||
|
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
|
||||||
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
|
||||||
|
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||||
|
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
|
||||||
|
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||||
|
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bitmap blur(Bitmap original, float radius) {
|
||||||
|
int w = original.getWidth();
|
||||||
|
int h = original.getHeight();
|
||||||
|
int[] currentPixels = new int[w * h];
|
||||||
|
original.getPixels(currentPixels, 0, w, 0, 0, w, h);
|
||||||
|
int cores = StackBlurManager.EXECUTOR_THREADS;
|
||||||
|
|
||||||
|
ArrayList<BlurTask> horizontal = new ArrayList<BlurTask>(cores);
|
||||||
|
ArrayList<BlurTask> vertical = new ArrayList<BlurTask>(cores);
|
||||||
|
for (int i = 0; i < cores; i++) {
|
||||||
|
horizontal.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 1));
|
||||||
|
vertical.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
StackBlurManager.EXECUTOR.invokeAll(horizontal);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
StackBlurManager.EXECUTOR.invokeAll(vertical);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bitmap.createBitmap(currentPixels, w, h, Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void blurIteration(int[] src, int w, int h, int radius, int cores, int core, int step) {
|
||||||
|
int x, y, xp, yp, i;
|
||||||
|
int sp;
|
||||||
|
int stack_start;
|
||||||
|
int stack_i;
|
||||||
|
|
||||||
|
int src_i;
|
||||||
|
int dst_i;
|
||||||
|
|
||||||
|
long sum_r, sum_g, sum_b,
|
||||||
|
sum_in_r, sum_in_g, sum_in_b,
|
||||||
|
sum_out_r, sum_out_g, sum_out_b;
|
||||||
|
|
||||||
|
int wm = w - 1;
|
||||||
|
int hm = h - 1;
|
||||||
|
int div = (radius * 2) + 1;
|
||||||
|
int mul_sum = stackblur_mul[radius];
|
||||||
|
byte shr_sum = stackblur_shr[radius];
|
||||||
|
int[] stack = new int[div];
|
||||||
|
|
||||||
|
if (step == 1) {
|
||||||
|
int minY = core * h / cores;
|
||||||
|
int maxY = (core + 1) * h / cores;
|
||||||
|
|
||||||
|
for (y = minY; y < maxY; y++) {
|
||||||
|
sum_r = sum_g = sum_b =
|
||||||
|
sum_in_r = sum_in_g = sum_in_b =
|
||||||
|
sum_out_r = sum_out_g = sum_out_b = 0;
|
||||||
|
|
||||||
|
src_i = w * y; // start of line (0,y)
|
||||||
|
|
||||||
|
for (i = 0; i <= radius; i++) {
|
||||||
|
stack_i = i;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (i + 1);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (i + 1);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (i + 1);
|
||||||
|
sum_out_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 1; i <= radius; i++) {
|
||||||
|
if (i <= wm) src_i += 1;
|
||||||
|
stack_i = i + radius;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (radius + 1 - i);
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sp = radius;
|
||||||
|
xp = radius;
|
||||||
|
if (xp > wm) xp = wm;
|
||||||
|
src_i = xp + y * w; // img.pix_ptr(xp, y);
|
||||||
|
dst_i = y * w; // img.pix_ptr(0, y);
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
src[dst_i] = (int)
|
||||||
|
((src[dst_i] & 0xff000000) |
|
||||||
|
((((sum_r * mul_sum) >>> shr_sum) & 0xff) << 16) |
|
||||||
|
((((sum_g * mul_sum) >>> shr_sum) & 0xff) << 8) |
|
||||||
|
((((sum_b * mul_sum) >>> shr_sum) & 0xff)));
|
||||||
|
dst_i += 1;
|
||||||
|
|
||||||
|
sum_r -= sum_out_r;
|
||||||
|
sum_g -= sum_out_g;
|
||||||
|
sum_b -= sum_out_b;
|
||||||
|
|
||||||
|
stack_start = sp + div - radius;
|
||||||
|
if (stack_start >= div) stack_start -= div;
|
||||||
|
stack_i = stack_start;
|
||||||
|
|
||||||
|
sum_out_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b -= (stack[stack_i] & 0xff);
|
||||||
|
|
||||||
|
if (xp < wm) {
|
||||||
|
src_i += 1;
|
||||||
|
++xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
sum_r += sum_in_r;
|
||||||
|
sum_g += sum_in_g;
|
||||||
|
sum_b += sum_in_b;
|
||||||
|
|
||||||
|
++sp;
|
||||||
|
if (sp >= div) sp = 0;
|
||||||
|
stack_i = sp;
|
||||||
|
|
||||||
|
sum_out_r += ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (stack[stack_i] & 0xff);
|
||||||
|
sum_in_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b -= (stack[stack_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
else if (step == 2) {
|
||||||
|
int minX = core * w / cores;
|
||||||
|
int maxX = (core + 1) * w / cores;
|
||||||
|
|
||||||
|
for (x = minX; x < maxX; x++) {
|
||||||
|
sum_r = sum_g = sum_b =
|
||||||
|
sum_in_r = sum_in_g = sum_in_b =
|
||||||
|
sum_out_r = sum_out_g = sum_out_b = 0;
|
||||||
|
|
||||||
|
src_i = x; // x,0
|
||||||
|
for (i = 0; i <= radius; i++) {
|
||||||
|
stack_i = i;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (i + 1);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (i + 1);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (i + 1);
|
||||||
|
sum_out_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
for (i = 1; i <= radius; i++) {
|
||||||
|
if (i <= hm) src_i += w; // +stride
|
||||||
|
|
||||||
|
stack_i = i + radius;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (radius + 1 - i);
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = radius;
|
||||||
|
yp = radius;
|
||||||
|
if (yp > hm) yp = hm;
|
||||||
|
src_i = x + yp * w; // img.pix_ptr(x, yp);
|
||||||
|
dst_i = x; // img.pix_ptr(x, 0);
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
src[dst_i] = (int)
|
||||||
|
((src[dst_i] & 0xff000000) |
|
||||||
|
((((sum_r * mul_sum) >>> shr_sum) & 0xff) << 16) |
|
||||||
|
((((sum_g * mul_sum) >>> shr_sum) & 0xff) << 8) |
|
||||||
|
((((sum_b * mul_sum) >>> shr_sum) & 0xff)));
|
||||||
|
dst_i += w;
|
||||||
|
|
||||||
|
sum_r -= sum_out_r;
|
||||||
|
sum_g -= sum_out_g;
|
||||||
|
sum_b -= sum_out_b;
|
||||||
|
|
||||||
|
stack_start = sp + div - radius;
|
||||||
|
if (stack_start >= div) stack_start -= div;
|
||||||
|
stack_i = stack_start;
|
||||||
|
|
||||||
|
sum_out_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b -= (stack[stack_i] & 0xff);
|
||||||
|
|
||||||
|
if (yp < hm) {
|
||||||
|
src_i += w; // stride
|
||||||
|
++yp;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
sum_r += sum_in_r;
|
||||||
|
sum_g += sum_in_g;
|
||||||
|
sum_b += sum_in_b;
|
||||||
|
|
||||||
|
++sp;
|
||||||
|
if (sp >= div) sp = 0;
|
||||||
|
stack_i = sp;
|
||||||
|
|
||||||
|
sum_out_r += ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (stack[stack_i] & 0xff);
|
||||||
|
sum_in_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b -= (stack[stack_i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BlurTask implements Callable<Void> {
|
||||||
|
private final int[] _src;
|
||||||
|
private final int _w;
|
||||||
|
private final int _h;
|
||||||
|
private final int _radius;
|
||||||
|
private final int _totalCores;
|
||||||
|
private final int _coreIndex;
|
||||||
|
private final int _round;
|
||||||
|
|
||||||
|
public BlurTask(int[] src, int w, int h, int radius, int totalCores, int coreIndex, int round) {
|
||||||
|
_src = src;
|
||||||
|
_w = w;
|
||||||
|
_h = h;
|
||||||
|
_radius = radius;
|
||||||
|
_totalCores = totalCores;
|
||||||
|
_coreIndex = coreIndex;
|
||||||
|
_round = round;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
blurIteration(_src, _w, _h, _radius, _totalCores, _coreIndex, _round);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* StackBlur v1.0 for Android
|
||||||
|
*
|
||||||
|
* @Author: Enrique López Mañas <eenriquelopez@gmail.com>
|
||||||
|
* http://www.lopez-manas.com
|
||||||
|
* <p/>
|
||||||
|
* Author of the original algorithm: Mario Klingemann <mario.quasimondo.com>
|
||||||
|
* <p/>
|
||||||
|
* This is a compromise between Gaussian Blur and Box blur
|
||||||
|
* It creates much better looking blurs than Box Blur, but is
|
||||||
|
* 7x faster than my Gaussian Blur implementation.
|
||||||
|
* <p/>
|
||||||
|
* I called it Stack Blur because this describes best how this
|
||||||
|
* filter works internally: it creates a kind of moving stack
|
||||||
|
* of colors whilst scanning through the image. Thereby it
|
||||||
|
* just has to add one new block of color to the right side
|
||||||
|
* of the stack and remove the leftmost color. The remaining
|
||||||
|
* colors on the topmost layer of the stack are either added on
|
||||||
|
* or reduced by one, depending on if they are on the right or
|
||||||
|
* on the left side of the stack.
|
||||||
|
* @copyright: Enrique López Mañas
|
||||||
|
* @license: Apache License 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.kabouzeid.gramophone.helper.bitmapblur;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class StackBlurManager {
|
||||||
|
static final int EXECUTOR_THREADS = Runtime.getRuntime().availableProcessors();
|
||||||
|
static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(EXECUTOR_THREADS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Original image
|
||||||
|
*/
|
||||||
|
private final Bitmap _image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most recent result of blurring
|
||||||
|
*/
|
||||||
|
private Bitmap _result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method of blurring
|
||||||
|
*/
|
||||||
|
private final BlurProcess _blurProcess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method (basic initialization and construction of the pixel array)
|
||||||
|
*
|
||||||
|
* @param image The image that will be analyed
|
||||||
|
*/
|
||||||
|
public StackBlurManager(Bitmap image) {
|
||||||
|
_image = image;
|
||||||
|
_blurProcess = new JavaBlurProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the image on the given radius. Radius must be at least 1
|
||||||
|
*
|
||||||
|
* @param radius
|
||||||
|
*/
|
||||||
|
public Bitmap process(int radius) {
|
||||||
|
_result = _blurProcess.blur(_image, radius);
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the blurred image as a bitmap
|
||||||
|
*
|
||||||
|
* @return blurred image
|
||||||
|
*/
|
||||||
|
public Bitmap returnBlurredImage() {
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the original image as a bitmap
|
||||||
|
*
|
||||||
|
* @return the original bitmap image
|
||||||
|
*/
|
||||||
|
public Bitmap getImage() {
|
||||||
|
return this._image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.kabouzeid.gramophone.interfaces;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public interface CabHolder {
|
||||||
|
|
||||||
|
MaterialCab openCab(final int menuRes, final MaterialCab.Callback callback);
|
||||||
|
}
|
||||||
|
|
@ -27,9 +27,8 @@ public class AlbumLoader {
|
||||||
final int artistId = cursor.getInt(3);
|
final int artistId = cursor.getInt(3);
|
||||||
final int songCount = cursor.getInt(4);
|
final int songCount = cursor.getInt(4);
|
||||||
final int year = cursor.getInt(5);
|
final int year = cursor.getInt(5);
|
||||||
final String albumArtPath = cursor.getString(6);
|
|
||||||
|
|
||||||
final Album album = new Album(id, albumName, artist, artistId, songCount, year, albumArtPath);
|
final Album album = new Album(id, albumName, artist, artistId, songCount, year);
|
||||||
albums.add(album);
|
albums.add(album);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -58,8 +57,6 @@ public class AlbumLoader {
|
||||||
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
||||||
/* 5 */
|
/* 5 */
|
||||||
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
|
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
|
||||||
/* 6 */
|
|
||||||
MediaStore.Audio.AlbumColumns.ALBUM_ART
|
|
||||||
}, selection, values, PreferenceUtils.getInstance(context).getAlbumSortOrder());
|
}, selection, values, PreferenceUtils.getInstance(context).getAlbumSortOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,9 +70,8 @@ public class AlbumLoader {
|
||||||
final int artistId = cursor.getInt(3);
|
final int artistId = cursor.getInt(3);
|
||||||
final int songCount = cursor.getInt(4);
|
final int songCount = cursor.getInt(4);
|
||||||
final int year = cursor.getInt(5);
|
final int year = cursor.getInt(5);
|
||||||
final String albumArtPath = cursor.getString(6);
|
|
||||||
|
|
||||||
album = new Album(id, albumName, artist, artistId, songCount, year, albumArtPath);
|
album = new Album(id, albumName, artist, artistId, songCount, year);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
|
|
@ -95,9 +91,8 @@ public class AlbumLoader {
|
||||||
final int artistId = cursor.getInt(3);
|
final int artistId = cursor.getInt(3);
|
||||||
final int songCount = cursor.getInt(4);
|
final int songCount = cursor.getInt(4);
|
||||||
final int year = cursor.getInt(5);
|
final int year = cursor.getInt(5);
|
||||||
final String albumArtPath = cursor.getString(6);
|
|
||||||
|
|
||||||
final Album album = new Album(id, albumName, artist, artistId, songCount, year, albumArtPath);
|
final Album album = new Album(id, albumName, artist, artistId, songCount, year);
|
||||||
albums.add(album);
|
albums.add(album);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,8 @@ public class AlbumSongLoader {
|
||||||
final long duration = cursor.getLong(4);
|
final long duration = cursor.getLong(4);
|
||||||
final int trackNumber = cursor.getInt(5);
|
final int trackNumber = cursor.getInt(5);
|
||||||
final int artistId = cursor.getInt(6);
|
final int artistId = cursor.getInt(6);
|
||||||
final long dateModified = cursor.getInt(7);
|
|
||||||
|
|
||||||
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, dateModified);
|
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
|
||||||
songs.add(song);
|
songs.add(song);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -54,9 +53,7 @@ public class AlbumSongLoader {
|
||||||
/* 5 */
|
/* 5 */
|
||||||
MediaStore.Audio.AudioColumns.TRACK,
|
MediaStore.Audio.AudioColumns.TRACK,
|
||||||
/* 6 */
|
/* 6 */
|
||||||
MediaStore.Audio.AudioColumns.ARTIST_ID,
|
MediaStore.Audio.AudioColumns.ARTIST_ID
|
||||||
/* 7 */
|
|
||||||
MediaStore.Audio.AudioColumns.DATE_MODIFIED
|
|
||||||
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
|
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
|
||||||
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
|
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
|
||||||
MediaStore.Audio.AudioColumns.ALBUM_ID + "=" + albumId, null,
|
MediaStore.Audio.AudioColumns.ALBUM_ID + "=" + albumId, null,
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,15 @@ import com.kabouzeid.gramophone.model.Album;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class ArtistAlbumLoader {
|
public class ArtistAlbumLoader {
|
||||||
|
|
||||||
public static List<Album> getArtistAlbumList(final Context context, final int artistId) {
|
public static ArrayList<Album> getArtistAlbumList(final Context context, final int artistId) {
|
||||||
Cursor cursor = makeArtistAlbumCursor(context, artistId);
|
Cursor cursor = makeArtistAlbumCursor(context, artistId);
|
||||||
List<Album> albums = new ArrayList<>();
|
ArrayList<Album> albums = new ArrayList<>();
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
final int id = cursor.getInt(0);
|
final int id = cursor.getInt(0);
|
||||||
|
|
@ -26,9 +25,8 @@ public class ArtistAlbumLoader {
|
||||||
final String artist = cursor.getString(2);
|
final String artist = cursor.getString(2);
|
||||||
final int songCount = cursor.getInt(3);
|
final int songCount = cursor.getInt(3);
|
||||||
final int year = cursor.getInt(4);
|
final int year = cursor.getInt(4);
|
||||||
final String albumArtPath = cursor.getString(5);
|
|
||||||
|
|
||||||
final Album album = new Album(id, albumName, artist, artistId, songCount, year, albumArtPath);
|
final Album album = new Album(id, albumName, artist, artistId, songCount, year);
|
||||||
albums.add(album);
|
albums.add(album);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -51,8 +49,6 @@ public class ArtistAlbumLoader {
|
||||||
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
|
||||||
/* 4 */
|
/* 4 */
|
||||||
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
|
MediaStore.Audio.AlbumColumns.FIRST_YEAR,
|
||||||
/* 5 */
|
|
||||||
MediaStore.Audio.AlbumColumns.ALBUM_ART
|
|
||||||
}, null, null, PreferenceUtils.getInstance(context).getArtistAlbumSortOrder());
|
}, null, null, PreferenceUtils.getInstance(context).getArtistAlbumSortOrder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,8 @@ public class ArtistSongLoader {
|
||||||
final long duration = cursor.getLong(4);
|
final long duration = cursor.getLong(4);
|
||||||
final int trackNumber = cursor.getInt(5);
|
final int trackNumber = cursor.getInt(5);
|
||||||
final int albumId = cursor.getInt(6);
|
final int albumId = cursor.getInt(6);
|
||||||
final long dateModified = cursor.getInt(7);
|
|
||||||
|
|
||||||
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, dateModified);
|
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
|
||||||
songs.add(song);
|
songs.add(song);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -54,9 +53,7 @@ public class ArtistSongLoader {
|
||||||
/* 5 */
|
/* 5 */
|
||||||
MediaStore.Audio.AudioColumns.TRACK,
|
MediaStore.Audio.AudioColumns.TRACK,
|
||||||
/* 6 */
|
/* 6 */
|
||||||
MediaStore.Audio.AudioColumns.ALBUM_ID,
|
MediaStore.Audio.AudioColumns.ALBUM_ID
|
||||||
/* 7 */
|
|
||||||
MediaStore.Audio.AudioColumns.DATE_MODIFIED
|
|
||||||
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
|
}, (MediaStore.Audio.AudioColumns.IS_MUSIC + "=1") + " AND " +
|
||||||
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
|
MediaStore.Audio.AudioColumns.TITLE + " != ''" + " AND " +
|
||||||
MediaStore.Audio.AudioColumns.ARTIST_ID + "=" + artistId, null,
|
MediaStore.Audio.AudioColumns.ARTIST_ID + "=" + artistId, null,
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,8 @@ public class PlaylistSongLoader {
|
||||||
final int albumId = cursor.getInt(6);
|
final int albumId = cursor.getInt(6);
|
||||||
final int artistId = cursor.getInt(7);
|
final int artistId = cursor.getInt(7);
|
||||||
final int idInPlaylist = cursor.getInt(8);
|
final int idInPlaylist = cursor.getInt(8);
|
||||||
final long dateModified = cursor.getInt(9);
|
|
||||||
|
|
||||||
final PlaylistSong song = new PlaylistSong(id, albumId, artistId, songName, artist, album, duration, trackNumber, playlistID, idInPlaylist, dateModified);
|
final PlaylistSong song = new PlaylistSong(id, albumId, artistId, songName, artist, album, duration, trackNumber, playlistID, idInPlaylist);
|
||||||
|
|
||||||
songs.add(song);
|
songs.add(song);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
|
|
@ -60,9 +59,7 @@ public class PlaylistSongLoader {
|
||||||
/* 7 */
|
/* 7 */
|
||||||
AudioColumns.ARTIST_ID,
|
AudioColumns.ARTIST_ID,
|
||||||
/* 8 */
|
/* 8 */
|
||||||
MediaStore.Audio.Playlists.Members._ID,
|
MediaStore.Audio.Playlists.Members._ID
|
||||||
/* 9 */
|
|
||||||
MediaStore.Audio.AudioColumns.DATE_MODIFIED
|
|
||||||
}, (AudioColumns.IS_MUSIC + "=1") + " AND " + AudioColumns.TITLE + " != ''", null,
|
}, (AudioColumns.IS_MUSIC + "=1") + " AND " + AudioColumns.TITLE + " != ''", null,
|
||||||
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
|
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,8 @@ public class SongLoader {
|
||||||
final int trackNumber = cursor.getInt(5);
|
final int trackNumber = cursor.getInt(5);
|
||||||
final int artistId = cursor.getInt(6);
|
final int artistId = cursor.getInt(6);
|
||||||
final int albumId = cursor.getInt(7);
|
final int albumId = cursor.getInt(7);
|
||||||
final long dateModified = cursor.getInt(8);
|
|
||||||
|
|
||||||
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, dateModified);
|
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
|
||||||
songs.add(song);
|
songs.add(song);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -68,9 +67,7 @@ public class SongLoader {
|
||||||
/* 6 */
|
/* 6 */
|
||||||
MediaStore.Audio.AudioColumns.ARTIST_ID,
|
MediaStore.Audio.AudioColumns.ARTIST_ID,
|
||||||
/* 7 */
|
/* 7 */
|
||||||
MediaStore.Audio.AudioColumns.ALBUM_ID,
|
MediaStore.Audio.AudioColumns.ALBUM_ID
|
||||||
/* 8 */
|
|
||||||
MediaStore.Audio.AudioColumns.DATE_MODIFIED
|
|
||||||
}, finalSelection, values, PreferenceUtils.getInstance(context).getSongSortOrder());
|
}, finalSelection, values, PreferenceUtils.getInstance(context).getSongSortOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,9 +84,8 @@ public class SongLoader {
|
||||||
final int trackNumber = cursor.getInt(5);
|
final int trackNumber = cursor.getInt(5);
|
||||||
final int artistId = cursor.getInt(6);
|
final int artistId = cursor.getInt(6);
|
||||||
final int albumId = cursor.getInt(7);
|
final int albumId = cursor.getInt(7);
|
||||||
final long dateModified = cursor.getInt(8);
|
|
||||||
|
|
||||||
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, dateModified);
|
final Song song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
|
||||||
songs.add(song);
|
songs.add(song);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
|
|
@ -111,8 +107,7 @@ public class SongLoader {
|
||||||
final int trackNumber = cursor.getInt(5);
|
final int trackNumber = cursor.getInt(5);
|
||||||
final int artistId = cursor.getInt(6);
|
final int artistId = cursor.getInt(6);
|
||||||
final int albumId = cursor.getInt(7);
|
final int albumId = cursor.getInt(7);
|
||||||
final long dateModified = cursor.getInt(8);
|
song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber);
|
||||||
song = new Song(id, albumId, artistId, songName, artist, album, duration, trackNumber, dateModified);
|
|
||||||
}
|
}
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,11 @@ public class DragSortRecycler extends RecyclerView.ItemDecoration implements Rec
|
||||||
rv.invalidateItemDecorations();// Redraw
|
rv.invalidateItemDecorations();// Redraw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void setIsDragging(final boolean dragging) {
|
private void setIsDragging(final boolean dragging) {
|
||||||
if (dragging != isDragging) {
|
if (dragging != isDragging) {
|
||||||
isDragging = dragging;
|
isDragging = dragging;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.kabouzeid.gramophone.model;
|
package com.kabouzeid.gramophone.model;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
|
|
@ -11,17 +13,15 @@ public class Album {
|
||||||
public final String artistName;
|
public final String artistName;
|
||||||
public final int songCount;
|
public final int songCount;
|
||||||
public final int year;
|
public final int year;
|
||||||
public final String albumArtPath; //used as cache key
|
|
||||||
|
|
||||||
public Album(final int id, final String title, final String artistName, final int artistId,
|
public Album(final int id, final String title, final String artistName, final int artistId,
|
||||||
final int songNumber, final int albumYear, final String albumArtPath) {
|
final int songNumber, final int albumYear) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.artistName = artistName;
|
this.artistName = artistName;
|
||||||
this.artistId = artistId;
|
this.artistId = artistId;
|
||||||
songCount = songNumber;
|
songCount = songNumber;
|
||||||
year = albumYear;
|
year = albumYear;
|
||||||
this.albumArtPath = albumArtPath != null ? albumArtPath : "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Album() {
|
public Album() {
|
||||||
|
|
@ -31,6 +31,49 @@ public class Album {
|
||||||
this.artistId = -1;
|
this.artistId = -1;
|
||||||
songCount = -1;
|
songCount = -1;
|
||||||
year = -1;
|
year = -1;
|
||||||
this.albumArtPath = "";
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + (title == null ? 0 : title.hashCode());
|
||||||
|
result = prime * result + (artistName == null ? 0 : artistName.hashCode());
|
||||||
|
result = prime * result + songCount;
|
||||||
|
result = prime * result + year;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Album other = (Album) obj;
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(title, other.title)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(artistName, other.artistName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (songCount != other.songCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return year == other.year;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.kabouzeid.gramophone.model;
|
package com.kabouzeid.gramophone.model;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
|
|
@ -22,4 +24,44 @@ public class Artist {
|
||||||
songCount = -1;
|
songCount = -1;
|
||||||
albumCount = -1;
|
albumCount = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + albumCount;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + (name == null ? 0 : name.hashCode());
|
||||||
|
result = prime * result + songCount;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Artist other = (Artist) obj;
|
||||||
|
if (albumCount != other.albumCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(name, other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return songCount == other.songCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,16 @@
|
||||||
package com.kabouzeid.gramophone.model;
|
package com.kabouzeid.gramophone.model;
|
||||||
|
|
||||||
public class Playlist {
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class Playlist implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3013703495354856981L;
|
||||||
|
|
||||||
public final int id;
|
public final int id;
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
|
|
@ -13,4 +23,36 @@ public class Playlist {
|
||||||
this.id = -1;
|
this.id = -1;
|
||||||
this.name = "";
|
this.name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + (name == null ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Playlist other = (Playlist) obj;
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return TextUtils.equals(name, other.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ public class PlaylistSong extends Song {
|
||||||
public final int idInPlayList;
|
public final int idInPlayList;
|
||||||
|
|
||||||
public PlaylistSong(final int id, final int albumId, final int artistId, final String title, final String artistName,
|
public PlaylistSong(final int id, final int albumId, final int artistId, final String title, final String artistName,
|
||||||
final String albumName, final long duration, final int trackNumber, final int playlistId, final int idInPlayList, final long dateModified) {
|
final String albumName, final long duration, final int trackNumber, final int playlistId, final int idInPlayList) {
|
||||||
super(id, albumId, artistId, title, artistName, albumName, duration, trackNumber, dateModified);
|
super(id, albumId, artistId, title, artistName, albumName, duration, trackNumber);
|
||||||
this.playlistId = playlistId;
|
this.playlistId = playlistId;
|
||||||
this.idInPlayList = idInPlayList;
|
this.idInPlayList = idInPlayList;
|
||||||
}
|
}
|
||||||
|
|
@ -19,4 +19,22 @@ public class PlaylistSong extends Song {
|
||||||
playlistId = -1;
|
playlistId = -1;
|
||||||
idInPlayList = -1;
|
idInPlayList = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + playlistId;
|
||||||
|
result = prime * result + idInPlayList;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (super.equals(obj)) {
|
||||||
|
final PlaylistSong other = (PlaylistSong) obj;
|
||||||
|
return playlistId == other.playlistId && idInPlayList == other.idInPlayList;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.kabouzeid.gramophone.model;
|
package com.kabouzeid.gramophone.model;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,10 +19,9 @@ public class Song implements Serializable {
|
||||||
public final String albumName;
|
public final String albumName;
|
||||||
public final long duration;
|
public final long duration;
|
||||||
public final int trackNumber;
|
public final int trackNumber;
|
||||||
public final long dateModified; //used as cache key
|
|
||||||
|
|
||||||
public Song(final int id, final int albumId, final int artistId, final String title, final String artistName,
|
public Song(final int id, final int albumId, final int artistId, final String title, final String artistName,
|
||||||
final String albumName, final long duration, final int trackNumber, final long dateModified) {
|
final String albumName, final long duration, final int trackNumber) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.albumId = albumId;
|
this.albumId = albumId;
|
||||||
this.artistId = artistId;
|
this.artistId = artistId;
|
||||||
|
|
@ -29,7 +30,6 @@ public class Song implements Serializable {
|
||||||
this.albumName = albumName;
|
this.albumName = albumName;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.trackNumber = trackNumber;
|
this.trackNumber = trackNumber;
|
||||||
this.dateModified = dateModified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Song() {
|
public Song() {
|
||||||
|
|
@ -41,6 +41,49 @@ public class Song implements Serializable {
|
||||||
this.albumName = "";
|
this.albumName = "";
|
||||||
this.duration = -1;
|
this.duration = -1;
|
||||||
this.trackNumber = -1;
|
this.trackNumber = -1;
|
||||||
this.dateModified = -1;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (albumName == null ? 0 : albumName.hashCode());
|
||||||
|
result = prime * result + (artistName == null ? 0 : artistName.hashCode());
|
||||||
|
result = prime * result + (int) duration;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + (title == null ? 0 : title.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Song other = (Song) obj;
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(albumName, other.albumName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(artistName, other.artistName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (duration != other.duration) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return TextUtils.equals(title, other.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ public class UIPreferenceChangedEvent {
|
||||||
public static final int COLORED_NAVIGATION_BAR_CURRENT_PLAYING_CHANGED = 6;
|
public static final int COLORED_NAVIGATION_BAR_CURRENT_PLAYING_CHANGED = 6;
|
||||||
public static final int COLORED_NAVIGATION_BAR_CHANGED = 10;
|
public static final int COLORED_NAVIGATION_BAR_CHANGED = 10;
|
||||||
public static final int COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED = 7;
|
public static final int COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED = 7;
|
||||||
public static final int PLAYBACK_CONTROLLER_CARD_CHANGED = 8;
|
|
||||||
public static final int TOOLBAR_TRANSPARENT_CHANGED = 9;
|
|
||||||
|
|
||||||
private final int action;
|
private final int action;
|
||||||
private final Object value;
|
private final Object value;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.views.CircleView;
|
import com.kabouzeid.gramophone.views.ColorView;
|
||||||
|
|
||||||
public class ColorChooserPreference extends Preference {
|
public class ColorChooserPreference extends Preference {
|
||||||
|
|
||||||
|
|
@ -43,11 +43,10 @@ public class ColorChooserPreference extends Preference {
|
||||||
|
|
||||||
private void invalidateColor() {
|
private void invalidateColor() {
|
||||||
if (mView != null) {
|
if (mView != null) {
|
||||||
CircleView circle = (CircleView) mView.findViewById(R.id.circle);
|
ColorView circle = (ColorView) mView.findViewById(R.id.circle);
|
||||||
if (this.color != 0) {
|
if (this.color != 0) {
|
||||||
circle.setVisibility(View.VISIBLE);
|
circle.setVisibility(View.VISIBLE);
|
||||||
circle.setBackgroundColor(color);
|
circle.setBackgroundColor(color);
|
||||||
circle.setBorderColor(border);
|
|
||||||
} else {
|
} else {
|
||||||
circle.setVisibility(View.GONE);
|
circle.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListene
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, AudioManager.OnAudioFocusChangeListener {
|
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, AudioManager.OnAudioFocusChangeListener {
|
||||||
public static final String ACTION_TOGGLE_PLAYBACK = "com.kabouzeid.gramophone.action.TOGGLE_PLAYBACK";
|
public static final String ACTION_TOGGLE_PLAYBACK = "com.kabouzeid.gramophone.action.TOGGLE_PLAYBACK";
|
||||||
|
|
@ -552,6 +553,18 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
saveState();
|
saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSongs(int position, List<Song> songs) {
|
||||||
|
playingQueue.addAll(position, songs);
|
||||||
|
originalPlayingQueue.addAll(position, songs);
|
||||||
|
saveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSongs(List<Song> songs) {
|
||||||
|
playingQueue.addAll(songs);
|
||||||
|
originalPlayingQueue.addAll(songs);
|
||||||
|
saveState();
|
||||||
|
}
|
||||||
|
|
||||||
public void removeSong(int position) {
|
public void removeSong(int position) {
|
||||||
if (getShuffleMode() == SHUFFLE_MODE_NONE) {
|
if (getShuffleMode() == SHUFFLE_MODE_NONE) {
|
||||||
playingQueue.remove(position);
|
playingQueue.remove(position);
|
||||||
|
|
@ -796,7 +809,7 @@ public class MusicService extends Service implements MediaPlayer.OnPreparedListe
|
||||||
//to let other apps know whats playing. i.E. last.fm (scrobbling) or musixmatch
|
//to let other apps know whats playing. i.E. last.fm (scrobbling) or musixmatch
|
||||||
final Intent intent = new Intent(what);
|
final Intent intent = new Intent(what);
|
||||||
final int position = getPosition();
|
final int position = getPosition();
|
||||||
if(position >= 0) {
|
if (position >= 0 && !playingQueue.isEmpty()) {
|
||||||
final Song currentSong = playingQueue.get(position);
|
final Song currentSong = playingQueue.get(position);
|
||||||
intent.putExtra("id", currentSong.id);
|
intent.putExtra("id", currentSong.id);
|
||||||
intent.putExtra("artist", currentSong.artistName);
|
intent.putExtra("artist", currentSong.artistName);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.animation.Animator;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
@ -10,24 +11,32 @@ import android.support.v4.util.Pair;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.transition.Transition;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewAnimationUtils;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.adapter.songadapter.AlbumSongAdapter;
|
import com.kabouzeid.gramophone.adapter.songadapter.AlbumSongAdapter;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.helper.bitmapblur.StackBlurManager;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||||
|
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
|
|
@ -51,22 +60,27 @@ import java.util.ArrayList;
|
||||||
* <p/>
|
* <p/>
|
||||||
* Should be kinda stable ONLY AS IT IS!!!
|
* Should be kinda stable ONLY AS IT IS!!!
|
||||||
*/
|
*/
|
||||||
public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorHolder {
|
public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorHolder, CabHolder {
|
||||||
|
|
||||||
public static final String TAG = AlbumDetailActivity.class.getSimpleName();
|
public static final String TAG = AlbumDetailActivity.class.getSimpleName();
|
||||||
private static final int TAG_EDITOR_REQUEST = 2001;
|
private static final int TAG_EDITOR_REQUEST = 2001;
|
||||||
private Album album;
|
private Album album;
|
||||||
|
|
||||||
private ObservableRecyclerView recyclerView;
|
private ObservableRecyclerView recyclerView;
|
||||||
private View statusBar;
|
private AlbumSongAdapter adapter;
|
||||||
|
private ArrayList<Song> songs;
|
||||||
private ImageView albumArtImageView;
|
private ImageView albumArtImageView;
|
||||||
|
private ImageView albumArtBackground;
|
||||||
private View songsBackgroundView;
|
private View songsBackgroundView;
|
||||||
private TextView albumTitleView;
|
private TextView albumTitleView;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
|
private MaterialCab cab;
|
||||||
private int headerOffset;
|
private int headerOffset;
|
||||||
private int titleViewHeight;
|
private int titleViewHeight;
|
||||||
private int albumArtViewHeight;
|
private int albumArtViewHeight;
|
||||||
private int toolbarColor;
|
private int toolbarColor;
|
||||||
|
private float toolbarAlpha;
|
||||||
|
private int bottomOffset;
|
||||||
|
|
||||||
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -82,9 +96,9 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + albumArtViewHeight));
|
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + albumArtViewHeight));
|
||||||
|
|
||||||
// Change alpha of overlay
|
// Change alpha of overlay
|
||||||
float alpha = Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
|
toolbarAlpha = Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, alpha, toolbarColor);
|
ViewUtil.setBackgroundAlpha(toolbar, toolbarAlpha, toolbarColor);
|
||||||
ViewUtil.setBackgroundAlpha(statusBar, alpha, toolbarColor);
|
setStatusBarColor(Util.getColorWithAlpha(cab != null && cab.isActive() ? 1 : toolbarAlpha, toolbarColor));
|
||||||
|
|
||||||
// Translate name text
|
// Translate name text
|
||||||
int maxTitleTranslationY = albumArtViewHeight;
|
int maxTitleTranslationY = albumArtViewHeight;
|
||||||
|
|
@ -92,26 +106,21 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
||||||
|
|
||||||
ViewHelper.setTranslationY(albumTitleView, titleTranslationY);
|
ViewHelper.setTranslationY(albumTitleView, titleTranslationY);
|
||||||
|
|
||||||
// Translate FAB
|
|
||||||
int fabTranslationY = titleTranslationY + titleViewHeight - (getFab().getHeight() / 2);
|
|
||||||
ViewHelper.setTranslationY(getFab(), fabTranslationY);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(true);
|
setStatusBarTransparent();
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_album_detail);
|
setContentView(R.layout.activity_album_detail);
|
||||||
|
|
||||||
App.bus.register(this);
|
App.bus.register(this);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
postponeEnterTransition();
|
postponeEnterTransition();
|
||||||
if (PreferenceUtils.getInstance(this).coloredNavigationBarAlbumEnabled())
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarAlbumEnabled())
|
||||||
getWindow().setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle intentExtras = getIntent().getExtras();
|
Bundle intentExtras = getIntent().getExtras();
|
||||||
|
|
@ -128,16 +137,29 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
setUpObservableListViewParams();
|
setUpObservableListViewParams();
|
||||||
setUpToolBar();
|
setUpToolBar();
|
||||||
setUpViews();
|
setUpViews();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
protected boolean shouldColorStatusBar() {
|
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||||
return false;
|
@Override
|
||||||
}
|
public void onTransitionStart(Transition transition) {
|
||||||
|
albumArtBackground.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldColorNavBar() {
|
public void onTransitionEnd(Transition transition) {
|
||||||
return false;
|
int cx = (albumArtBackground.getLeft() + albumArtBackground.getRight()) / 2;
|
||||||
|
int cy = (albumArtBackground.getTop() + albumArtBackground.getBottom()) / 2;
|
||||||
|
int finalRadius = Math.max(albumArtBackground.getWidth(), albumArtBackground.getHeight());
|
||||||
|
|
||||||
|
Animator animator = ViewAnimationUtils.createCircularReveal(albumArtBackground, cx, cy, albumArtImageView.getWidth() / 2, finalRadius);
|
||||||
|
animator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
animator.setDuration(1000);
|
||||||
|
animator.start();
|
||||||
|
|
||||||
|
albumArtBackground.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -147,21 +169,23 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
||||||
|
albumArtBackground = (ImageView) findViewById(R.id.album_art_background);
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
recyclerView = (ObservableRecyclerView) findViewById(R.id.list);
|
recyclerView = (ObservableRecyclerView) findViewById(R.id.list);
|
||||||
albumTitleView = (TextView) findViewById(R.id.album_title);
|
albumTitleView = (TextView) findViewById(R.id.album_title);
|
||||||
songsBackgroundView = findViewById(R.id.list_background);
|
songsBackgroundView = findViewById(R.id.list_background);
|
||||||
statusBar = findViewById(R.id.statusBar);
|
// statusBar = findViewById(R.id.status_bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpObservableListViewParams() {
|
private void setUpObservableListViewParams() {
|
||||||
|
bottomOffset = getResources().getDimensionPixelSize(R.dimen.bottom_offset_fab_activity);
|
||||||
albumArtViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
albumArtViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
||||||
toolbarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
toolbarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
||||||
int toolbarHeight = Util.getActionBarSize(this);
|
int toolbarHeight = Util.getActionBarSize(this);
|
||||||
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
||||||
headerOffset = toolbarHeight;
|
headerOffset = toolbarHeight;
|
||||||
if (Util.isAtLeastKitKat())
|
if (Util.isAtLeastKitKat())
|
||||||
headerOffset += getResources().getDimensionPixelSize(R.dimen.statusMargin);
|
headerOffset += getResources().getDimensionPixelSize(R.dimen.status_bar_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpViews() {
|
private void setUpViews() {
|
||||||
|
|
@ -181,18 +205,22 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
.resetViewBeforeLoading(true)
|
.resetViewBeforeLoading(true)
|
||||||
.build(),
|
.build(),
|
||||||
new SimpleImageLoadingListener() {
|
new SimpleImageLoadingListener() {
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
applyPalette(null);
|
applyPalette(null);
|
||||||
if (Util.isAtLeastLollipop()) startPostponedEnterTransition();
|
albumArtBackground.setImageBitmap(new StackBlurManager(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art)).process(10));
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
startPostponedEnterTransition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||||
applyPalette(loadedImage);
|
applyPalette(loadedImage);
|
||||||
if (Util.isAtLeastLollipop()) startPostponedEnterTransition();
|
albumArtBackground.setImageBitmap(new StackBlurManager(loadedImage).process(10));
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
startPostponedEnterTransition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -202,16 +230,16 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
Palette.from(bitmap)
|
Palette.from(bitmap)
|
||||||
.generate(new Palette.PaletteAsyncListener() {
|
.generate(new Palette.PaletteAsyncListener() {
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
||||||
if (vibrantSwatch != null) {
|
if (vibrantSwatch != null) {
|
||||||
toolbarColor = vibrantSwatch.getRgb();
|
toolbarColor = vibrantSwatch.getRgb();
|
||||||
albumTitleView.setBackgroundColor(toolbarColor);
|
albumTitleView.setBackgroundColor(toolbarColor);
|
||||||
albumTitleView.setTextColor(vibrantSwatch.getTitleTextColor());
|
albumTitleView.setTextColor(Util.getOpaqueColor(vibrantSwatch.getTitleTextColor()));
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(AlbumDetailActivity.this).coloredNavigationBarAlbumEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(AlbumDetailActivity.this).coloredNavigationBarAlbumEnabled())
|
||||||
getWindow().setNavigationBarColor(toolbarColor);
|
setNavigationBarColor(toolbarColor);
|
||||||
notifyTaskColorChange(toolbarColor);
|
notifyTaskColorChange(toolbarColor);
|
||||||
} else {
|
} else {
|
||||||
resetColors();
|
resetColors();
|
||||||
|
|
@ -223,7 +251,7 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void resetColors() {
|
private void resetColors() {
|
||||||
int titleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
|
int titleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
|
||||||
int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
||||||
|
|
@ -233,7 +261,7 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
albumTitleView.setTextColor(titleTextColor);
|
albumTitleView.setTextColor(titleTextColor);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
||||||
getWindow().setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
||||||
|
|
||||||
notifyTaskColorChange(toolbarColor);
|
notifyTaskColorChange(toolbarColor);
|
||||||
}
|
}
|
||||||
|
|
@ -248,18 +276,18 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
return toolbarColor;
|
return toolbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void setNavigationBarColored(boolean colored) {
|
private void setNavigationBarColored(boolean colored) {
|
||||||
if (colored) {
|
if (colored) {
|
||||||
if (Util.isAtLeastLollipop()) getWindow().setNavigationBarColor(toolbarColor);
|
setNavigationBarColor(toolbarColor);
|
||||||
} else {
|
} else {
|
||||||
if (Util.isAtLeastLollipop()) getWindow().setNavigationBarColor(Color.BLACK);
|
setNavigationBarColor(Color.BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpListView() {
|
private void setUpListView() {
|
||||||
recyclerView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
recyclerView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||||
recyclerView.setPadding(0, albumArtViewHeight + titleViewHeight, 0, 0);
|
recyclerView.setPadding(0, albumArtViewHeight + titleViewHeight, 0, bottomOffset);
|
||||||
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||||
contentView.post(new Runnable() {
|
contentView.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -279,10 +307,10 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpSongsAdapter() {
|
private void setUpSongsAdapter() {
|
||||||
final ArrayList<Song> songs = AlbumSongLoader.getAlbumSongList(this, album.id);
|
songs = AlbumSongLoader.getAlbumSongList(this, album.id);
|
||||||
final AlbumSongAdapter albumSongAdapter = new AlbumSongAdapter(this, songs);
|
adapter = new AlbumSongAdapter(this, songs, this);
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||||
recyclerView.setAdapter(albumSongAdapter);
|
recyclerView.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -346,6 +374,19 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case DataBaseChangedEvent.SONGS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.ALBUMS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||||
|
songs = AlbumSongLoader.getAlbumSongList(this, album.id);
|
||||||
|
adapter.updateDataSet(songs);
|
||||||
|
if (songs.size() < 1) finish();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onUIPreferenceChanged(UIPreferenceChangedEvent event) {
|
public void onUIPreferenceChanged(UIPreferenceChangedEvent event) {
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
|
|
@ -360,4 +401,37 @@ public class AlbumDetailActivity extends AbsFabActivity implements PaletteColorH
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
App.bus.unregister(this);
|
App.bus.unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MaterialCab openCab(int menuRes, final MaterialCab.Callback callback) {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
cab = new MaterialCab(this, R.id.cab_stub)
|
||||||
|
.setMenu(menuRes)
|
||||||
|
.setBackgroundColor(getPaletteColor())
|
||||||
|
.start(new MaterialCab.Callback() {
|
||||||
|
@Override
|
||||||
|
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||||
|
setStatusBarColor(Util.getOpaqueColor(toolbarColor));
|
||||||
|
return callback.onCabCreated(materialCab, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||||
|
return callback.onCabItemClicked(menuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabFinished(MaterialCab materialCab) {
|
||||||
|
setStatusBarColor(Util.getColorWithAlpha(toolbarAlpha, toolbarColor));
|
||||||
|
return callback.onCabFinished(materialCab);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
else super.onBackPressed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.animation.Animator;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
@ -17,11 +18,13 @@ import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.view.ViewAnimationUtils;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||||
|
|
@ -30,6 +33,8 @@ import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.adapter.ArtistAlbumAdapter;
|
import com.kabouzeid.gramophone.adapter.ArtistAlbumAdapter;
|
||||||
import com.kabouzeid.gramophone.adapter.songadapter.ArtistSongAdapter;
|
import com.kabouzeid.gramophone.adapter.songadapter.ArtistSongAdapter;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.helper.bitmapblur.StackBlurManager;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
|
||||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistBiographyLoader;
|
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistBiographyLoader;
|
||||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageUrlLoader;
|
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageUrlLoader;
|
||||||
|
|
@ -38,8 +43,10 @@ import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||||
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||||
|
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||||
import com.kabouzeid.gramophone.model.Album;
|
import com.kabouzeid.gramophone.model.Album;
|
||||||
import com.kabouzeid.gramophone.model.Artist;
|
import com.kabouzeid.gramophone.model.Artist;
|
||||||
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
|
|
@ -55,33 +62,38 @@ import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListene
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Should be kinda stable ONLY AS IT IS!!!
|
* Should be kinda stable ONLY AS IT IS!!!
|
||||||
*/
|
*/
|
||||||
public class ArtistDetailActivity extends AbsFabActivity implements PaletteColorHolder {
|
public class ArtistDetailActivity extends AbsFabActivity implements PaletteColorHolder, CabHolder {
|
||||||
|
|
||||||
public static final String TAG = ArtistDetailActivity.class.getSimpleName();
|
public static final String TAG = ArtistDetailActivity.class.getSimpleName();
|
||||||
private Artist artist;
|
private Artist artist;
|
||||||
|
|
||||||
private ObservableListView songListView;
|
private ObservableListView songListView;
|
||||||
private View statusBar;
|
|
||||||
private ImageView artistImage;
|
private ImageView artistImage;
|
||||||
|
private ImageView artistImageBackground;
|
||||||
private View songsBackgroundView;
|
private View songsBackgroundView;
|
||||||
private TextView artistNameTv;
|
private TextView artistNameTv;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
|
private MaterialCab cab;
|
||||||
private int headerOffset;
|
private int headerOffset;
|
||||||
private int titleViewHeight;
|
private int titleViewHeight;
|
||||||
private int artistImageViewHeight;
|
private int artistImageViewHeight;
|
||||||
private int toolbarColor;
|
private int toolbarColor;
|
||||||
|
private float toolbarAlpha;
|
||||||
|
private int bottomOffset;
|
||||||
|
|
||||||
private View songListHeader;
|
private View songListHeader;
|
||||||
private RecyclerView albumRecyclerView;
|
private RecyclerView albumRecyclerView;
|
||||||
private Spanned biography;
|
private Spanned biography;
|
||||||
private ArtistAlbumAdapter albumAdapter;
|
private ArtistAlbumAdapter albumAdapter;
|
||||||
|
private ArtistSongAdapter songAdapter;
|
||||||
|
private ArrayList<Song> songs;
|
||||||
|
private ArrayList<Album> albums;
|
||||||
|
|
||||||
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
private final SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -97,9 +109,9 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + artistImageViewHeight));
|
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + artistImageViewHeight));
|
||||||
|
|
||||||
// Change alpha of overlay
|
// Change alpha of overlay
|
||||||
float alpha = Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
|
toolbarAlpha = Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, alpha, toolbarColor);
|
ViewUtil.setBackgroundAlpha(toolbar, toolbarAlpha, toolbarColor);
|
||||||
ViewUtil.setBackgroundAlpha(statusBar, alpha, toolbarColor);
|
setStatusBarColor(Util.getColorWithAlpha(cab != null && cab.isActive() ? 1 : toolbarAlpha, toolbarColor));
|
||||||
|
|
||||||
// Translate name text
|
// Translate name text
|
||||||
int maxTitleTranslationY = artistImageViewHeight;
|
int maxTitleTranslationY = artistImageViewHeight;
|
||||||
|
|
@ -107,27 +119,23 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
||||||
|
|
||||||
ViewHelper.setTranslationY(artistNameTv, titleTranslationY);
|
ViewHelper.setTranslationY(artistNameTv, titleTranslationY);
|
||||||
|
|
||||||
// Translate FAB
|
|
||||||
int fabTranslationY = titleTranslationY + titleViewHeight - (getFab().getHeight() / 2);
|
|
||||||
ViewHelper.setTranslationY(getFab(), fabTranslationY);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(true);
|
setStatusBarTransparent();
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_artist_detail);
|
setContentView(R.layout.activity_artist_detail);
|
||||||
|
|
||||||
App.bus.register(this);
|
App.bus.register(this);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
postponeEnterTransition();
|
postponeEnterTransition();
|
||||||
if (PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
||||||
getWindow().setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
getIntentExtras();
|
getIntentExtras();
|
||||||
|
|
@ -139,42 +147,56 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
getSupportActionBar().setTitle(null);
|
getSupportActionBar().setTitle(null);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
fixLollipopTransitionImageWrongSize();
|
fixLollipopTransitionImageWrongSize();
|
||||||
startPostponedEnterTransition();
|
startPostponedEnterTransition();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
protected boolean shouldColorStatusBar() {
|
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||||
return false;
|
@Override
|
||||||
}
|
public void onTransitionStart(Transition transition) {
|
||||||
|
artistImageBackground.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldColorNavBar() {
|
public void onTransitionEnd(Transition transition) {
|
||||||
return false;
|
int cx = (artistImageBackground.getLeft() + artistImageBackground.getRight()) / 2;
|
||||||
|
int cy = (artistImageBackground.getTop() + artistImageBackground.getBottom()) / 2;
|
||||||
|
int finalRadius = Math.max(artistImageBackground.getWidth(), artistImageBackground.getHeight());
|
||||||
|
|
||||||
|
Animator animator = ViewAnimationUtils.createCircularReveal(artistImageBackground, cx, cy, artistImage.getWidth() / 2, finalRadius);
|
||||||
|
animator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
animator.setDuration(1000);
|
||||||
|
animator.start();
|
||||||
|
|
||||||
|
artistImageBackground.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
artistImage = (ImageView) findViewById(R.id.artist_image);
|
artistImage = (ImageView) findViewById(R.id.artist_image);
|
||||||
|
artistImageBackground = (ImageView) findViewById(R.id.artist_image_background);
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
songListView = (ObservableListView) findViewById(R.id.list);
|
songListView = (ObservableListView) findViewById(R.id.list);
|
||||||
artistNameTv = (TextView) findViewById(R.id.artist_name);
|
artistNameTv = (TextView) findViewById(R.id.artist_name);
|
||||||
songsBackgroundView = findViewById(R.id.list_background);
|
songsBackgroundView = findViewById(R.id.list_background);
|
||||||
statusBar = findViewById(R.id.statusBar);
|
|
||||||
|
|
||||||
songListHeader = LayoutInflater.from(this).inflate(R.layout.artist_detail_header, songListView, false);
|
songListHeader = LayoutInflater.from(this).inflate(R.layout.artist_detail_header, songListView, false);
|
||||||
albumRecyclerView = (RecyclerView) songListHeader.findViewById(R.id.recycler_view);
|
albumRecyclerView = (RecyclerView) songListHeader.findViewById(R.id.recycler_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpObservableListViewParams() {
|
private void setUpObservableListViewParams() {
|
||||||
|
bottomOffset = getResources().getDimensionPixelSize(R.dimen.bottom_offset_fab_activity);
|
||||||
artistImageViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
artistImageViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
||||||
toolbarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
toolbarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
||||||
int toolbarHeight = Util.getActionBarSize(this);
|
int toolbarHeight = Util.getActionBarSize(this);
|
||||||
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
||||||
headerOffset = toolbarHeight;
|
headerOffset = toolbarHeight;
|
||||||
if (Util.isAtLeastKitKat())
|
if (Util.isAtLeastKitKat())
|
||||||
headerOffset += getResources().getDimensionPixelSize(R.dimen.statusMargin);
|
headerOffset += getResources().getDimensionPixelSize(R.dimen.status_bar_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -196,22 +218,22 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
loadBiography();
|
loadBiography();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void setNavigationBarColored(boolean colored) {
|
private void setNavigationBarColored(boolean colored) {
|
||||||
if (colored) {
|
if (colored) {
|
||||||
if (Util.isAtLeastLollipop()) getWindow().setNavigationBarColor(toolbarColor);
|
setNavigationBarColor(toolbarColor);
|
||||||
} else {
|
} else {
|
||||||
if (Util.isAtLeastLollipop()) getWindow().setNavigationBarColor(Color.BLACK);
|
setNavigationBarColor(Color.BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpSongListView() {
|
private void setUpSongListView() {
|
||||||
songListView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
songListView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||||
songListView.setPadding(0, artistImageViewHeight + titleViewHeight, 0, 0);
|
songListView.setPadding(0, artistImageViewHeight + titleViewHeight, 0, bottomOffset);
|
||||||
songListView.addHeaderView(songListHeader);
|
songListView.addHeaderView(songListHeader);
|
||||||
|
|
||||||
final ArrayList<Song> songs = ArtistSongLoader.getArtistSongList(this, artist.id);
|
songs = ArtistSongLoader.getArtistSongList(this, artist.id);
|
||||||
ArtistSongAdapter songAdapter = new ArtistSongAdapter(this, songs);
|
songAdapter = new ArtistSongAdapter(this, songs, this);
|
||||||
songListView.setAdapter(songAdapter);
|
songListView.setAdapter(songAdapter);
|
||||||
|
|
||||||
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||||
|
|
@ -222,23 +244,12 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
observableScrollViewCallbacks.onScrollChanged(-(artistImageViewHeight + titleViewHeight), false, false);
|
observableScrollViewCallbacks.onScrollChanged(-(artistImageViewHeight + titleViewHeight), false, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
songListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
// header view has position 0
|
|
||||||
if (position == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MusicPlayerRemote.openQueue(songs, position - 1, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpAlbumRecyclerView() {
|
private void setUpAlbumRecyclerView() {
|
||||||
albumRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
|
albumRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
|
||||||
List<Album> albums = ArtistAlbumLoader.getArtistAlbumList(this, artist.id);
|
albums = ArtistAlbumLoader.getArtistAlbumList(this, artist.id);
|
||||||
albumAdapter = new ArtistAlbumAdapter(this, albums);
|
albumAdapter = new ArtistAlbumAdapter(this, albums, this);
|
||||||
albumRecyclerView.setAdapter(albumAdapter);
|
albumRecyclerView.setAdapter(albumAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,6 +275,8 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpArtistImageAndApplyPalette(final boolean forceDownload) {
|
private void setUpArtistImageAndApplyPalette(final boolean forceDownload) {
|
||||||
|
final StackBlurManager defaultArtistImageBlurManager = new StackBlurManager(BitmapFactory.decodeResource(getResources(), R.drawable.default_artist_image));
|
||||||
|
artistImageBackground.setImageBitmap(defaultArtistImageBlurManager.process(10));
|
||||||
LastFMArtistImageUrlLoader.loadArtistImageUrl(this, artist.name, forceDownload, new LastFMArtistImageUrlLoader.ArtistImageUrlLoaderCallback() {
|
LastFMArtistImageUrlLoader.loadArtistImageUrl(this, artist.name, forceDownload, new LastFMArtistImageUrlLoader.ArtistImageUrlLoaderCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onArtistImageUrlLoaded(final String url) {
|
public void onArtistImageUrlLoaded(final String url) {
|
||||||
|
|
@ -279,11 +292,13 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
applyPalette(null);
|
applyPalette(null);
|
||||||
|
artistImageBackground.setImageBitmap(defaultArtistImageBlurManager.returnBlurredImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||||
applyPalette(loadedImage);
|
applyPalette(loadedImage);
|
||||||
|
artistImageBackground.setImageBitmap(new StackBlurManager(loadedImage).process(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -295,16 +310,16 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
Palette.from(bitmap)
|
Palette.from(bitmap)
|
||||||
.generate(new Palette.PaletteAsyncListener() {
|
.generate(new Palette.PaletteAsyncListener() {
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
||||||
if (vibrantSwatch != null) {
|
if (vibrantSwatch != null) {
|
||||||
toolbarColor = vibrantSwatch.getRgb();
|
toolbarColor = vibrantSwatch.getRgb();
|
||||||
artistNameTv.setBackgroundColor(vibrantSwatch.getRgb());
|
artistNameTv.setBackgroundColor(vibrantSwatch.getRgb());
|
||||||
artistNameTv.setTextColor(vibrantSwatch.getTitleTextColor());
|
artistNameTv.setTextColor(Util.getOpaqueColor(vibrantSwatch.getTitleTextColor()));
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(ArtistDetailActivity.this).coloredNavigationBarArtistEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(ArtistDetailActivity.this).coloredNavigationBarArtistEnabled())
|
||||||
getWindow().setNavigationBarColor(vibrantSwatch.getRgb());
|
setNavigationBarColor(vibrantSwatch.getRgb());
|
||||||
notifyTaskColorChange(toolbarColor);
|
notifyTaskColorChange(toolbarColor);
|
||||||
} else {
|
} else {
|
||||||
resetColors();
|
resetColors();
|
||||||
|
|
@ -333,7 +348,7 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
return toolbarColor;
|
return toolbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void resetColors() {
|
private void resetColors() {
|
||||||
int titleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
|
int titleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
|
||||||
int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
||||||
|
|
@ -343,7 +358,7 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
artistNameTv.setTextColor(titleTextColor);
|
artistNameTv.setTextColor(titleTextColor);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarArtistEnabled())
|
||||||
getWindow().setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
setNavigationBarColor(DialogUtils.resolveColor(this, R.attr.default_bar_color));
|
||||||
|
|
||||||
notifyTaskColorChange(toolbarColor);
|
notifyTaskColorChange(toolbarColor);
|
||||||
}
|
}
|
||||||
|
|
@ -411,7 +426,7 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
toolbar.setEnabled(false);
|
toolbar.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void fixLollipopTransitionImageWrongSize() {
|
private void fixLollipopTransitionImageWrongSize() {
|
||||||
getWindow().getSharedElementEnterTransition().addListener(new Transition.TransitionListener() {
|
getWindow().getSharedElementEnterTransition().addListener(new Transition.TransitionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -441,6 +456,22 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case DataBaseChangedEvent.SONGS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.ALBUMS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.ARTISTS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||||
|
songs = ArtistSongLoader.getArtistSongList(this, artist.id);
|
||||||
|
songAdapter.updateDataSet(songs);
|
||||||
|
albums = ArtistAlbumLoader.getArtistAlbumList(this, artist.id);
|
||||||
|
albumAdapter.updateDataSet(albums);
|
||||||
|
if (songs.size() < 1) finish();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onUIPreferenceChanged(UIPreferenceChangedEvent event) {
|
public void onUIPreferenceChanged(UIPreferenceChangedEvent event) {
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
|
|
@ -455,4 +486,37 @@ public class ArtistDetailActivity extends AbsFabActivity implements PaletteColor
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
App.bus.unregister(this);
|
App.bus.unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MaterialCab openCab(int menuRes, final MaterialCab.Callback callback) {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
cab = new MaterialCab(this, R.id.cab_stub)
|
||||||
|
.setMenu(menuRes)
|
||||||
|
.setBackgroundColor(getPaletteColor())
|
||||||
|
.start(new MaterialCab.Callback() {
|
||||||
|
@Override
|
||||||
|
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||||
|
setStatusBarColor(Util.getOpaqueColor(toolbarColor));
|
||||||
|
return callback.onCabCreated(materialCab, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||||
|
return callback.onCabItemClicked(menuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCabFinished(MaterialCab materialCab) {
|
||||||
|
setStatusBarColor(Util.getColorWithAlpha(toolbarAlpha, toolbarColor));
|
||||||
|
return callback.onCabFinished(materialCab);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
else super.onBackPressed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.design.widget.NavigationView;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
|
@ -16,22 +20,23 @@ import android.support.v7.internal.view.menu.MenuPopupHelper;
|
||||||
import android.support.v7.widget.ActionMenuPresenter;
|
import android.support.v7.widget.ActionMenuPresenter;
|
||||||
import android.support.v7.widget.ActionMenuView;
|
import android.support.v7.widget.ActionMenuView;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.SubMenu;
|
import android.view.SubMenu;
|
||||||
import android.widget.FrameLayout;
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.astuetz.PagerSlidingTabStrip;
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.adapter.PagerAdapter;
|
import com.kabouzeid.gramophone.adapter.PagerAdapter;
|
||||||
import com.kabouzeid.gramophone.dialogs.AboutDialog;
|
import com.kabouzeid.gramophone.dialogs.AboutDialog;
|
||||||
import com.kabouzeid.gramophone.dialogs.CreatePlaylistDialog;
|
import com.kabouzeid.gramophone.dialogs.CreatePlaylistDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||||
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
||||||
|
|
@ -40,7 +45,6 @@ import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.NavigationDrawerFragment;
|
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AbsMainActivityFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AbsMainActivityFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AlbumViewFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AlbumViewFragment;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
|
|
@ -57,46 +61,37 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class MainActivity extends AbsFabActivity
|
public class MainActivity extends AbsFabActivity
|
||||||
implements NavigationDrawerFragment.NavigationDrawerCallbacks, KabViewsDisableAble {
|
implements KabViewsDisableAble, CabHolder, View.OnClickListener {
|
||||||
|
|
||||||
public static final String TAG = MainActivity.class.getSimpleName();
|
public static final String TAG = MainActivity.class.getSimpleName();
|
||||||
|
|
||||||
private DrawerLayout drawerLayout;
|
private DrawerLayout drawerLayout;
|
||||||
private ActionBarDrawerToggle drawerToggle;
|
private ActionBarDrawerToggle drawerToggle;
|
||||||
private NavigationDrawerFragment navigationDrawerFragment;
|
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private PagerAdapter pagerAdapter;
|
private PagerAdapter pagerAdapter;
|
||||||
private ViewPager viewPager;
|
private ViewPager viewPager;
|
||||||
private PagerSlidingTabStrip slidingTabLayout;
|
private TabLayout tabLayout;
|
||||||
private int currentPage = -1;
|
private int currentPage = -1;
|
||||||
|
private MaterialCab cab;
|
||||||
|
private NavigationView navigationView;
|
||||||
|
private View navigationDrawerHeader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(!Util.isAtLeastLollipop());
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
initViews();
|
initViews();
|
||||||
navigationDrawerFragment.setUp(
|
|
||||||
drawerLayout
|
|
||||||
);
|
|
||||||
setUpDrawerLayout();
|
setUpDrawerLayout();
|
||||||
setUpToolBar();
|
setUpToolBar();
|
||||||
setUpViewPager();
|
setUpViewPager();
|
||||||
|
|
||||||
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarOtherScreensEnabled())
|
||||||
|
setNavigationBarThemeColor();
|
||||||
|
|
||||||
handlePlaybackIntent(getIntent());
|
handlePlaybackIntent(getIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorStatusBar() {
|
|
||||||
return !Util.isAtLeastLollipop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return PreferenceUtils.getInstance(this).coloredNavigationBarOtherScreensEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpViewPager() {
|
private void setUpViewPager() {
|
||||||
pagerAdapter = new PagerAdapter(this, getSupportFragmentManager());
|
pagerAdapter = new PagerAdapter(this, getSupportFragmentManager());
|
||||||
final PagerAdapter.MusicFragments[] fragments = PagerAdapter.MusicFragments.values();
|
final PagerAdapter.MusicFragments[] fragments = PagerAdapter.MusicFragments.values();
|
||||||
|
|
@ -110,52 +105,119 @@ public class MainActivity extends AbsFabActivity
|
||||||
int startPosition = PreferenceUtils.getInstance(this).getDefaultStartPage();
|
int startPosition = PreferenceUtils.getInstance(this).getDefaultStartPage();
|
||||||
startPosition = startPosition == -1 ? PreferenceUtils.getInstance(this).getLastStartPage() : startPosition;
|
startPosition = startPosition == -1 ? PreferenceUtils.getInstance(this).getLastStartPage() : startPosition;
|
||||||
currentPage = startPosition;
|
currentPage = startPosition;
|
||||||
viewPager.setCurrentItem(startPosition);
|
|
||||||
|
|
||||||
navigationDrawerFragment.setItemChecked(startPosition);
|
navigationView.getMenu().getItem(startPosition).setChecked(true);
|
||||||
|
|
||||||
slidingTabLayout.setIndicatorColor(ThemeSingleton.get().positiveColor);
|
tabLayout.setupWithViewPager(viewPager);
|
||||||
slidingTabLayout.setViewPager(viewPager);
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
|
|
||||||
slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(final int position) {
|
public void onPageSelected(int position) {
|
||||||
navigationDrawerFragment.setItemChecked(position);
|
navigationView.getMenu().getItem(position).setChecked(true);
|
||||||
currentPage = position;
|
currentPage = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrollStateChanged(int state) {
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
viewPager.setCurrentItem(startPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||||
slidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.tabs);
|
tabLayout = (TabLayout) findViewById(R.id.tabs);
|
||||||
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||||
navigationDrawerFragment = (NavigationDrawerFragment)
|
navigationView = (NavigationView) findViewById(R.id.nav_view);
|
||||||
getFragmentManager().findFragmentById(R.id.navigation_drawer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpToolBar() {
|
private void setUpToolBar() {
|
||||||
setTitle(getResources().getString(R.string.app_name));
|
setTitle(getResources().getString(R.string.app_name));
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
setToolBarTransparent(PreferenceUtils.getInstance(this).transparentToolbar());
|
setToolBarColor();
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
setUpDrawerToggle();
|
setUpDrawerToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setToolBarTransparent(boolean transparent) {
|
private void setToolBarColor() {
|
||||||
float alpha = transparent ? 0.9f : 1f;
|
final int colorPrimary = getThemeColorPrimary();
|
||||||
final int colorPrimary = PreferenceUtils.getInstance(this).getThemeColorPrimary();
|
toolbar.setBackgroundColor(colorPrimary);
|
||||||
ViewUtil.setBackgroundAlpha(toolbar, alpha, colorPrimary);
|
tabLayout.setBackgroundColor(colorPrimary);
|
||||||
ViewUtil.setBackgroundAlpha(slidingTabLayout, alpha, colorPrimary);
|
}
|
||||||
|
|
||||||
|
private void setUpNavigationView() {
|
||||||
|
final int colorAccent = ThemeSingleton.get().positiveColor;
|
||||||
|
navigationView.setItemTextColor(new ColorStateList(
|
||||||
|
new int[][]{
|
||||||
|
//{-android.R.attr.state_enabled}, // disabled
|
||||||
|
{android.R.attr.state_checked}, // checked
|
||||||
|
{} // default
|
||||||
|
},
|
||||||
|
new int[]{
|
||||||
|
// 0,
|
||||||
|
colorAccent,
|
||||||
|
ThemeSingleton.get().darkTheme ? Color.argb(222, 255, 255, 255) : Color.argb(222, 0, 0, 0)
|
||||||
|
}
|
||||||
|
));
|
||||||
|
navigationView.setItemIconTintList(new ColorStateList(
|
||||||
|
new int[][]{
|
||||||
|
//{-android.R.attr.state_enabled}, // disabled
|
||||||
|
{android.R.attr.state_checked}, // checked
|
||||||
|
{} // default
|
||||||
|
},
|
||||||
|
new int[]{
|
||||||
|
// 0,
|
||||||
|
colorAccent,
|
||||||
|
ThemeSingleton.get().darkTheme ? Color.argb(138, 255, 255, 255) : Color.argb(138, 0, 0, 0)
|
||||||
|
}
|
||||||
|
));
|
||||||
|
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onNavigationItemSelected(MenuItem menuItem) {
|
||||||
|
drawerLayout.closeDrawers();
|
||||||
|
switch (menuItem.getItemId()) {
|
||||||
|
case R.id.nav_songs:
|
||||||
|
menuItem.setChecked(true);
|
||||||
|
viewPager.setCurrentItem(PagerAdapter.MusicFragments.SONG.ordinal(), true);
|
||||||
|
break;
|
||||||
|
case R.id.nav_albums:
|
||||||
|
menuItem.setChecked(true);
|
||||||
|
viewPager.setCurrentItem(PagerAdapter.MusicFragments.ALBUM.ordinal(), true);
|
||||||
|
break;
|
||||||
|
case R.id.nav_artists:
|
||||||
|
menuItem.setChecked(true);
|
||||||
|
viewPager.setCurrentItem(PagerAdapter.MusicFragments.ARTIST.ordinal(), true);
|
||||||
|
break;
|
||||||
|
case R.id.nav_playlists:
|
||||||
|
menuItem.setChecked(true);
|
||||||
|
viewPager.setCurrentItem(PagerAdapter.MusicFragments.PLAYLIST.ordinal(), true);
|
||||||
|
break;
|
||||||
|
case R.id.nav_settings:
|
||||||
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
break;
|
||||||
|
case R.id.nav_about:
|
||||||
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
new AboutDialog().show(getSupportFragmentManager(), "ABOUT_DIALOG");
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpDrawerToggle() {
|
private void setUpDrawerToggle() {
|
||||||
|
|
@ -175,19 +237,8 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpDrawerLayout() {
|
private void setUpDrawerLayout() {
|
||||||
drawerLayout.setStatusBarBackgroundColor(PreferenceUtils
|
drawerLayout.setStatusBarBackgroundColor(PreferenceUtils.getInstance(this).getThemeColorPrimaryDarker());
|
||||||
.getInstance(this).getThemeColorPrimaryDarker());
|
setUpNavigationView();
|
||||||
|
|
||||||
FrameLayout navDrawerFrame = (FrameLayout) findViewById(R.id.nav_drawer_frame);
|
|
||||||
int navDrawerMargin = getResources().getDimensionPixelSize(R.dimen.nav_drawer_margin);
|
|
||||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
|
||||||
int navDrawerWidthLimit = getResources().getDimensionPixelSize(R.dimen.nav_drawer_width_limit);
|
|
||||||
int navDrawerWidth = displayMetrics.widthPixels - navDrawerMargin;
|
|
||||||
if (navDrawerWidth > navDrawerWidthLimit) {
|
|
||||||
navDrawerWidth = navDrawerWidthLimit;
|
|
||||||
}
|
|
||||||
navDrawerFrame.setLayoutParams(new DrawerLayout.LayoutParams(navDrawerWidth,
|
|
||||||
DrawerLayout.LayoutParams.MATCH_PARENT, Gravity.START));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -202,21 +253,26 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNavigationDrawerHeader() {
|
private void updateNavigationDrawerHeader() {
|
||||||
if (navigationDrawerFragment != null) {
|
Song song = MusicPlayerRemote.getCurrentSong();
|
||||||
Song song = MusicPlayerRemote.getCurrentSong();
|
if (song.id != -1) {
|
||||||
if (song.id != -1) {
|
if (navigationDrawerHeader == null) {
|
||||||
navigationDrawerFragment.getSongTitle().setText(song.title);
|
navigationDrawerHeader = navigationView.inflateHeaderView(R.layout.navigation_drawer_header);
|
||||||
navigationDrawerFragment.getSongArtist().setText(song.artistName);
|
navigationDrawerHeader.setOnClickListener(this);
|
||||||
ImageLoader.getInstance().displayImage(
|
|
||||||
MusicUtil.getAlbumArtUri(song.albumId).toString(),
|
|
||||||
navigationDrawerFragment.getAlbumArtImageView(),
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cacheInMemory(true)
|
|
||||||
.showImageOnFail(R.drawable.default_album_art)
|
|
||||||
.resetViewBeforeLoading(true)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
((TextView) navigationDrawerHeader.findViewById(R.id.song_title)).setText(song.title);
|
||||||
|
((TextView) navigationDrawerHeader.findViewById(R.id.song_artist)).setText(song.artistName);
|
||||||
|
ImageLoader.getInstance().displayImage(
|
||||||
|
MusicUtil.getAlbumArtUri(song.albumId).toString(),
|
||||||
|
((ImageView) navigationDrawerHeader.findViewById(R.id.album_art)),
|
||||||
|
new DisplayImageOptions.Builder()
|
||||||
|
.cacheInMemory(true)
|
||||||
|
.showImageOnFail(R.drawable.default_album_art)
|
||||||
|
.resetViewBeforeLoading(true)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
navigationView.removeHeaderView(navigationDrawerHeader);
|
||||||
|
navigationDrawerHeader = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,37 +305,6 @@ public class MainActivity extends AbsFabActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNavigationDrawerItemSelected(int position) {
|
|
||||||
if (position == NavigationDrawerFragment.NAVIGATION_DRAWER_HEADER) {
|
|
||||||
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithFab(new Pair[]{
|
|
||||||
Pair.create(navigationDrawerFragment.getAlbumArtImageView(),
|
|
||||||
getResources().getString(R.string.transition_album_cover)
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
} else if (position == NavigationDrawerFragment.ABOUT_INDEX) {
|
|
||||||
drawerLayout.closeDrawers();
|
|
||||||
new Handler().postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
new AboutDialog().show(getSupportFragmentManager(), "ABOUT_DIALOG");
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
} else if (position == NavigationDrawerFragment.SETTINGS_INDEX) {
|
|
||||||
drawerLayout.closeDrawers();
|
|
||||||
new Handler().postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
} else {
|
|
||||||
if (viewPager != null) {
|
|
||||||
viewPager.setCurrentItem(position, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
if (isAlbumPage()) {
|
if (isAlbumPage()) {
|
||||||
|
|
@ -343,17 +368,17 @@ public class MainActivity extends AbsFabActivity
|
||||||
public void onUIPreferenceChangedEvent(UIPreferenceChangedEvent event) {
|
public void onUIPreferenceChangedEvent(UIPreferenceChangedEvent event) {
|
||||||
super.onUIPreferenceChangedEvent(event);
|
super.onUIPreferenceChangedEvent(event);
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
case UIPreferenceChangedEvent.TOOLBAR_TRANSPARENT_CHANGED:
|
|
||||||
setToolBarTransparent((boolean) event.getValue());
|
|
||||||
break;
|
|
||||||
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED:
|
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED:
|
||||||
setShouldColorNavBar((boolean) event.getValue());
|
if ((boolean) event.getValue()) setNavigationBarThemeColor();
|
||||||
|
else resetNavigationBarColor();
|
||||||
break;
|
break;
|
||||||
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_CHANGED:
|
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_CHANGED:
|
||||||
try {
|
try {
|
||||||
setShouldColorNavBar(((Set) event.getValue()).contains(PreferenceUtils.COLORED_NAVIGATION_BAR_OTHER_SCREENS));
|
if (((Set) event.getValue()).contains(PreferenceUtils.COLORED_NAVIGATION_BAR_OTHER_SCREENS))
|
||||||
|
setNavigationBarThemeColor();
|
||||||
|
else resetNavigationBarColor();
|
||||||
} catch (NullPointerException ignored) {
|
} catch (NullPointerException ignored) {
|
||||||
setShouldColorNavBar(false);
|
resetNavigationBarColor();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -361,11 +386,9 @@ public class MainActivity extends AbsFabActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (navigationDrawerFragment.isDrawerOpen()) {
|
if (drawerLayout.isDrawerOpen(navigationView)) drawerLayout.closeDrawers();
|
||||||
drawerLayout.closeDrawers();
|
else if (cab != null && cab.isActive()) cab.finish();
|
||||||
return;
|
else super.onBackPressed();
|
||||||
}
|
|
||||||
super.onBackPressed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -553,4 +576,25 @@ public class MainActivity extends AbsFabActivity
|
||||||
});
|
});
|
||||||
return super.onMenuOpened(featureId, menu);
|
return super.onMenuOpened(featureId, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
cab = new MaterialCab(this, R.id.cab_stub)
|
||||||
|
.setMenu(menu)
|
||||||
|
.setBackgroundColor(PreferenceUtils.getInstance(this).getThemeColorPrimary())
|
||||||
|
.start(callback);
|
||||||
|
return cab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (v == navigationDrawerHeader) {
|
||||||
|
NavigationUtil.openCurrentPlayingIfPossible(this, getSharedViewsWithFab(new Pair[]{
|
||||||
|
Pair.create(((ImageView) navigationDrawerHeader.findViewById(R.id.album_art)),
|
||||||
|
getResources().getString(R.string.transition_album_cover)
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.animation.Animator;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.transition.Transition;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewAnimationUtils;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
@ -21,17 +25,16 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||||
import com.kabouzeid.gramophone.App;
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
|
||||||
import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
|
import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageUrlLoader;
|
import com.kabouzeid.gramophone.helper.bitmapblur.StackBlurManager;
|
||||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||||
|
import com.kabouzeid.gramophone.misc.SmallTransitionListener;
|
||||||
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.UIPreferenceChangedEvent;
|
|
||||||
import com.kabouzeid.gramophone.service.MusicService;
|
import com.kabouzeid.gramophone.service.MusicService;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
||||||
|
|
@ -40,24 +43,22 @@ import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||||
import com.squareup.otto.Subscribe;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class MusicControllerActivity extends AbsFabActivity {
|
public class MusicControllerActivity extends AbsFabActivity {
|
||||||
|
|
||||||
public static final String TAG = MusicControllerActivity.class.getSimpleName();
|
public static final String TAG = MusicControllerActivity.class.getSimpleName();
|
||||||
private static final int DEFAULT_DELAY = 350;
|
private static final int COLOR_TRANSITION_TIME = 400;
|
||||||
private static final int DEFAULT_ANIMATION_TIME = 1000;
|
|
||||||
|
|
||||||
private Song song;
|
private Song song;
|
||||||
private ImageView albumArt;
|
private SquareIfPlaceImageView albumArt;
|
||||||
private ImageView artistImage;
|
private ImageView albumArtBackground;
|
||||||
private TextView songTitle;
|
private TextView songTitle;
|
||||||
private TextView songArtist;
|
private TextView songArtist;
|
||||||
private TextView currentSongProgress;
|
private TextView currentSongProgress;
|
||||||
|
|
@ -69,30 +70,58 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
private ImageButton repeatButton;
|
private ImageButton repeatButton;
|
||||||
private ImageButton shuffleButton;
|
private ImageButton shuffleButton;
|
||||||
private View mediaControllerContainer;
|
private View mediaControllerContainer;
|
||||||
|
private Toolbar toolbar;
|
||||||
private int lastFooterColor = -1;
|
private int lastFooterColor = -1;
|
||||||
|
private int lastTextColor = -2;
|
||||||
private boolean killThreads = false;
|
private boolean killThreads = false;
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
private boolean opaqueToolBar = PreferenceUtils.getInstance(this).opaqueToolbarNowPlaying();
|
||||||
|
private boolean forceSquareAlbumArt = PreferenceUtils.getInstance(this).forceAlbumArtSquared();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(true);
|
setStatusBarTransparent();
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_music_controller);
|
setContentView(R.layout.activity_music_controller);
|
||||||
|
|
||||||
App.bus.register(this);
|
|
||||||
|
|
||||||
initViews();
|
initViews();
|
||||||
|
albumArtBackground.setAlpha(0.7f);
|
||||||
|
|
||||||
moveSeekBarIntoPlace();
|
moveSeekBarIntoPlace();
|
||||||
|
|
||||||
setUpMusicControllers();
|
setUpMusicControllers();
|
||||||
|
|
||||||
prepareViewsForOpenAnimation();
|
albumArt.forceSquare(forceSquareAlbumArt);
|
||||||
|
setToolbarOpaque(opaqueToolBar);
|
||||||
|
|
||||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setTitle(null);
|
getSupportActionBar().setTitle(null);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
getWindow().getEnterTransition().addListener(new SmallTransitionListener() {
|
||||||
|
@Override
|
||||||
|
public void onTransitionStart(Transition transition) {
|
||||||
|
mediaControllerContainer.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionEnd(Transition transition) {
|
||||||
|
int cx = (getFab().getLeft() + getFab().getRight()) / 2;
|
||||||
|
int cy = (getFab().getTop() + getFab().getBottom()) / 2;
|
||||||
|
int finalRadius = Math.max(mediaControllerContainer.getWidth(), mediaControllerContainer.getHeight());
|
||||||
|
|
||||||
|
Animator animator = ViewAnimationUtils.createCircularReveal(mediaControllerContainer, cx, cy, getFab().getWidth() / 2, finalRadius);
|
||||||
|
animator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
animator.setDuration(1000);
|
||||||
|
animator.start();
|
||||||
|
|
||||||
|
mediaControllerContainer.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -101,22 +130,13 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
getFab().setOnLongClickListener(null);
|
getFab().setOnLongClickListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorStatusBar() {
|
|
||||||
return false; // let other code handle this below
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return false; // let other code handle this below
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveSeekBarIntoPlace() {
|
private void moveSeekBarIntoPlace() {
|
||||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
// RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
||||||
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
// progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||||
final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
|
// final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
|
||||||
lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(progressSlider.getMeasuredHeight() / 2));
|
// lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(progressSlider.getMeasuredHeight() / 2));
|
||||||
progressSlider.setLayoutParams(lp);
|
// progressSlider.setLayoutParams(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
|
|
@ -124,8 +144,8 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
prevButton = (ImageButton) findViewById(R.id.prev_button);
|
prevButton = (ImageButton) findViewById(R.id.prev_button);
|
||||||
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
|
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
|
||||||
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
|
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
|
||||||
albumArt = (ImageView) findViewById(R.id.album_art);
|
albumArt = (SquareIfPlaceImageView) findViewById(R.id.album_art);
|
||||||
artistImage = (ImageView) findViewById(R.id.artist_image);
|
albumArtBackground = (ImageView) findViewById(R.id.album_art_background);
|
||||||
songTitle = (TextView) findViewById(R.id.song_title);
|
songTitle = (TextView) findViewById(R.id.song_title);
|
||||||
songArtist = (TextView) findViewById(R.id.song_artist);
|
songArtist = (TextView) findViewById(R.id.song_artist);
|
||||||
currentSongProgress = (TextView) findViewById(R.id.song_current_progress);
|
currentSongProgress = (TextView) findViewById(R.id.song_current_progress);
|
||||||
|
|
@ -133,6 +153,7 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
footer = findViewById(R.id.footer);
|
footer = findViewById(R.id.footer);
|
||||||
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
|
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
|
||||||
mediaControllerContainer = findViewById(R.id.media_controller_container);
|
mediaControllerContainer = findViewById(R.id.media_controller_container);
|
||||||
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpMusicControllers() {
|
private void setUpMusicControllers() {
|
||||||
|
|
@ -140,43 +161,13 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
setUpRepeatButton();
|
setUpRepeatButton();
|
||||||
setUpShuffleButton();
|
setUpShuffleButton();
|
||||||
setUpProgressSlider();
|
setUpProgressSlider();
|
||||||
setUpBox(PreferenceUtils.getInstance(this).playbackControllerBoxEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void setUpBox(boolean boxEnabled) {
|
|
||||||
if (boxEnabled) {
|
|
||||||
if (Util.isAtLeastLollipop()) {
|
|
||||||
mediaControllerContainer.setElevation(getResources().getDimensionPixelSize(R.dimen.cardview_default_elevation));
|
|
||||||
}
|
|
||||||
mediaControllerContainer.setBackgroundColor(
|
|
||||||
DialogUtils.resolveColor(this, R.attr.music_controller_container_color));
|
|
||||||
} else {
|
|
||||||
if (Util.isAtLeastLollipop() && !Util.isInPortraitMode(this)) {
|
|
||||||
mediaControllerContainer.setElevation(getResources().getDimensionPixelSize(R.dimen.cardview_default_elevation));
|
|
||||||
mediaControllerContainer.setBackgroundColor(
|
|
||||||
DialogUtils.resolveColor(this, R.attr.music_controller_container_color));
|
|
||||||
} else {
|
|
||||||
mediaControllerContainer.setBackground(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setTint(SeekBar seekBar, int color) {
|
private static void setTint(SeekBar seekBar, int color) {
|
||||||
ColorStateList s1 = ColorStateList.valueOf(color);
|
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
seekBar.setThumbTintList(s1);
|
|
||||||
seekBar.setProgressTintList(s1);
|
|
||||||
} else {
|
|
||||||
seekBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
|
|
||||||
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpProgressSlider() {
|
private void setUpProgressSlider() {
|
||||||
setTint(progressSlider, ThemeSingleton.get().positiveColor);
|
|
||||||
progressSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
progressSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
|
@ -228,7 +219,7 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_48dp,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_48dp,
|
||||||
ThemeSingleton.get().positiveColor));
|
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_48dp,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_48dp,
|
||||||
|
|
@ -255,19 +246,15 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
break;
|
break;
|
||||||
case MusicService.REPEAT_MODE_ALL:
|
case MusicService.REPEAT_MODE_ALL:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_48dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_48dp,
|
||||||
ThemeSingleton.get().positiveColor));
|
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_48dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_48dp,
|
||||||
ThemeSingleton.get().positiveColor));
|
getThemeColorAccent() == Color.WHITE ? Color.BLACK : getThemeColorAccent()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareViewsForOpenAnimation() {
|
|
||||||
footer.setPivotY(0);
|
|
||||||
footer.setScaleY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTag() {
|
public String getTag() {
|
||||||
|
|
@ -277,6 +264,7 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
updateControllerState();
|
||||||
startMusicControllerStateUpdateThread();
|
startMusicControllerStateUpdateThread();
|
||||||
updateCurrentSong();
|
updateCurrentSong();
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +272,6 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
private void updateCurrentSong() {
|
private void updateCurrentSong() {
|
||||||
getCurrentSong();
|
getCurrentSong();
|
||||||
setHeadersText();
|
setHeadersText();
|
||||||
setUpArtistArt();
|
|
||||||
setUpAlbumArtAndApplyPalette();
|
setUpAlbumArtAndApplyPalette();
|
||||||
totalSongDuration.setText(MusicUtil.getReadableDurationString(song.duration));
|
totalSongDuration.setText(MusicUtil.getReadableDurationString(song.duration));
|
||||||
currentSongProgress.setText(MusicUtil.getReadableDurationString(-1));
|
currentSongProgress.setText(MusicUtil.getReadableDurationString(-1));
|
||||||
|
|
@ -307,17 +294,18 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
new DisplayImageOptions.Builder()
|
new DisplayImageOptions.Builder()
|
||||||
.cacheInMemory(true)
|
.cacheInMemory(true)
|
||||||
.showImageOnFail(R.drawable.default_album_art)
|
.showImageOnFail(R.drawable.default_album_art)
|
||||||
.resetViewBeforeLoading(true)
|
|
||||||
.build(),
|
.build(),
|
||||||
new SimpleImageLoadingListener() {
|
new SimpleImageLoadingListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||||
applyPalette(null);
|
applyPalette(null);
|
||||||
|
albumArtBackground.setImageBitmap(new StackBlurManager(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art)).process(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||||
applyPalette(loadedImage);
|
applyPalette(loadedImage);
|
||||||
|
albumArtBackground.setImageBitmap(new StackBlurManager(loadedImage).process(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -333,8 +321,7 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
if (vibrantSwatch != null) {
|
if (vibrantSwatch != null) {
|
||||||
final int swatchRgb = vibrantSwatch.getRgb();
|
final int swatchRgb = vibrantSwatch.getRgb();
|
||||||
animateColorChange(swatchRgb);
|
animateColorChange(swatchRgb);
|
||||||
songTitle.setTextColor(vibrantSwatch.getTitleTextColor());
|
animateTextColorChange(Util.getOpaqueColor(vibrantSwatch.getTitleTextColor()));
|
||||||
songArtist.setTextColor(vibrantSwatch.getBodyTextColor());
|
|
||||||
notifyTaskColorChange(swatchRgb);
|
notifyTaskColorChange(swatchRgb);
|
||||||
} else {
|
} else {
|
||||||
resetColors();
|
resetColors();
|
||||||
|
|
@ -347,48 +334,51 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetColors() {
|
private void resetColors() {
|
||||||
final int songTitleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
|
final int textColor = Util.getOpaqueColor(DialogUtils.resolveColor(this, R.attr.title_text_color));
|
||||||
final int artistNameTextColor = DialogUtils.resolveColor(this, R.attr.caption_text_color);
|
|
||||||
final int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
final int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
|
||||||
|
|
||||||
animateColorChange(defaultBarColor);
|
animateColorChange(defaultBarColor);
|
||||||
|
animateTextColorChange(textColor);
|
||||||
|
|
||||||
songTitle.setTextColor(songTitleTextColor);
|
currentSongProgress.setTextColor(DialogUtils.resolveColor(MusicControllerActivity.this, R.attr.themed_drawable_color));
|
||||||
songArtist.setTextColor(artistNameTextColor);
|
totalSongDuration.setTextColor(DialogUtils.resolveColor(MusicControllerActivity.this, R.attr.themed_drawable_color));
|
||||||
|
|
||||||
notifyTaskColorChange(defaultBarColor);
|
notifyTaskColorChange(defaultBarColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void animateColorChange(final int newColor) {
|
private void animateColorChange(final int newColor) {
|
||||||
if (lastFooterColor != -1 && lastFooterColor != newColor) {
|
if (lastFooterColor != -1 && lastFooterColor != newColor) {
|
||||||
ViewUtil.animateViewColor(footer, lastFooterColor, newColor, 300);
|
ViewUtil.animateViewColor(footer, lastFooterColor, newColor, COLOR_TRANSITION_TIME);
|
||||||
|
|
||||||
|
if (opaqueToolBar)
|
||||||
|
ViewUtil.animateViewColor(toolbar, lastFooterColor, newColor, COLOR_TRANSITION_TIME);
|
||||||
|
else toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||||
} else {
|
} else {
|
||||||
footer.setBackgroundColor(newColor);
|
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 (opaqueToolBar) setStatusBarColor(newColor);
|
||||||
|
else setStatusBarColor(Color.TRANSPARENT);
|
||||||
|
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarCurrentPlayingEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarCurrentPlayingEnabled())
|
||||||
getWindow().setNavigationBarColor(newColor);
|
setNavigationBarColor(newColor);
|
||||||
lastFooterColor = newColor;
|
lastFooterColor = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpArtistArt() {
|
private void animateTextColorChange(final int newColor) {
|
||||||
if (artistImage != null) {
|
if (lastTextColor != -2 && lastTextColor != newColor) {
|
||||||
artistImage.setImageResource(R.drawable.default_artist_image);
|
ViewUtil.animateTextColor(songTitle, lastTextColor, newColor, COLOR_TRANSITION_TIME);
|
||||||
LastFMArtistImageUrlLoader.loadArtistImageUrl(this, song.artistName, false, new LastFMArtistImageUrlLoader.ArtistImageUrlLoaderCallback() {
|
ViewUtil.animateTextColor(songArtist, lastTextColor, newColor, COLOR_TRANSITION_TIME);
|
||||||
@Override
|
} else {
|
||||||
public void onArtistImageUrlLoaded(String url) {
|
songTitle.setTextColor(newColor);
|
||||||
ImageLoader.getInstance().displayImage(url,
|
songArtist.setTextColor(newColor);
|
||||||
artistImage,
|
|
||||||
new DisplayImageOptions.Builder()
|
|
||||||
.cacheInMemory(true)
|
|
||||||
.cacheOnDisk(true)
|
|
||||||
.showImageOnFail(R.drawable.default_artist_image)
|
|
||||||
.resetViewBeforeLoading(true)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
lastTextColor = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getCurrentSong() {
|
private void getCurrentSong() {
|
||||||
|
|
@ -430,9 +420,8 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateControllerState() {
|
protected void updateControllerState() {
|
||||||
super.updateControllerState();
|
updateFabState();
|
||||||
updateRepeatState();
|
updateRepeatState();
|
||||||
updateShuffleState();
|
updateShuffleState();
|
||||||
}
|
}
|
||||||
|
|
@ -459,14 +448,6 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
killThreads = true;
|
killThreads = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
|
||||||
super.onWindowFocusChanged(hasFocus);
|
|
||||||
if (hasFocus) {
|
|
||||||
animateActivityOpened(DEFAULT_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.menu_music_playing, menu);
|
getMenuInflater().inflate(R.menu.menu_music_playing, menu);
|
||||||
|
|
@ -513,28 +494,16 @@ public class MusicControllerActivity extends AbsFabActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateActivityOpened(int startDelay) {
|
private void setToolbarOpaque(boolean toolbarOpaque) {
|
||||||
ViewPropertyAnimator.animate(footer)
|
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.album_art_frame).getLayoutParams();
|
||||||
.scaleX(1)
|
if (!toolbarOpaque) {
|
||||||
.scaleY(1)
|
if (Build.VERSION.SDK_INT > 16) {
|
||||||
.setInterpolator(new DecelerateInterpolator(4))
|
params.removeRule(RelativeLayout.BELOW);
|
||||||
.setDuration(DEFAULT_ANIMATION_TIME)
|
} else {
|
||||||
.setStartDelay(startDelay)
|
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
.start();
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
}
|
params.addRule(RelativeLayout.ABOVE, R.id.footer_frame);
|
||||||
|
}
|
||||||
@Subscribe
|
} else params.addRule(RelativeLayout.BELOW, R.id.toolbar_frame);
|
||||||
public void onUIPrefsChanged(UIPreferenceChangedEvent event) {
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case UIPreferenceChangedEvent.PLAYBACK_CONTROLLER_CARD_CHANGED:
|
|
||||||
setUpBox((boolean) event.getValue());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
App.bus.unregister(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities;
|
package com.kabouzeid.gramophone.ui.activities;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
@ -10,39 +8,45 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.afollestad.materialcab.MaterialCab;
|
||||||
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.adapter.songadapter.PlaylistSongAdapter;
|
import com.kabouzeid.gramophone.adapter.songadapter.PlaylistSongAdapter;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
import com.kabouzeid.gramophone.loader.PlaylistLoader;
|
||||||
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
|
import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||||
import com.kabouzeid.gramophone.misc.DragSortRecycler;
|
import com.kabouzeid.gramophone.misc.DragSortRecycler;
|
||||||
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
import com.kabouzeid.gramophone.util.PlaylistsUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class PlaylistDetailActivity extends AbsFabActivity {
|
public class PlaylistDetailActivity extends AbsFabActivity implements CabHolder {
|
||||||
|
|
||||||
public static final String TAG = PlaylistDetailActivity.class.getSimpleName();
|
public static final String TAG = PlaylistDetailActivity.class.getSimpleName();
|
||||||
private Playlist playlist;
|
private Playlist playlist;
|
||||||
|
private MaterialCab cab;
|
||||||
|
private PlaylistSongAdapter adapter;
|
||||||
|
private ArrayList<PlaylistSong> songs;
|
||||||
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(!Util.isAtLeastLollipop());
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_playlist_detail);
|
setContentView(R.layout.activity_playlist_detail);
|
||||||
|
|
||||||
getIntentExtras();
|
getIntentExtras();
|
||||||
|
|
||||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
|
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
|
||||||
final ArrayList<PlaylistSong> songs = PlaylistSongLoader.getPlaylistSongList(this, playlist.id);
|
songs = PlaylistSongLoader.getPlaylistSongList(this, playlist.id);
|
||||||
final PlaylistSongAdapter adapter = new PlaylistSongAdapter(this, songs);
|
adapter = new PlaylistSongAdapter(this, songs, this);
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
|
|
@ -72,16 +76,12 @@ public class PlaylistDetailActivity extends AbsFabActivity {
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setTitle(playlist.name);
|
getSupportActionBar().setTitle(playlist.name);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarPlaylistEnabled())
|
||||||
protected boolean shouldColorStatusBar() {
|
setNavigationBarThemeColor();
|
||||||
return true;
|
setStatusBarThemeColor();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
App.bus.register(this);
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return PreferenceUtils.getInstance(this).coloredNavigationBarPlaylistEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getIntentExtras() {
|
private void getIntentExtras() {
|
||||||
|
|
@ -123,4 +123,40 @@ public class PlaylistDetailActivity extends AbsFabActivity {
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
cab = new MaterialCab(this, R.id.cab_stub)
|
||||||
|
.setMenu(menu)
|
||||||
|
.setBackgroundColor(PreferenceUtils.getInstance(this).getThemeColorPrimary())
|
||||||
|
.start(callback);
|
||||||
|
return cab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
App.bus.unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDataBaseEvent(DataBaseChangedEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case DataBaseChangedEvent.PLAYLISTS_CHANGED:
|
||||||
|
case DataBaseChangedEvent.DATABASE_CHANGED:
|
||||||
|
songs = PlaylistSongLoader.getPlaylistSongList(this, playlist.id);
|
||||||
|
adapter.updateDataSet(songs);
|
||||||
|
findViewById(android.R.id.empty).setVisibility(
|
||||||
|
songs.size() == 0 ? View.VISIBLE : View.GONE
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (cab != null && cab.isActive()) cab.finish();
|
||||||
|
else super.onBackPressed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ public class SearchActivity extends AbsBaseActivity {
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(false);
|
|
||||||
setTitle(null);
|
setTitle(null);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_search);
|
setContentView(R.layout.activity_search);
|
||||||
|
|
@ -60,16 +59,9 @@ public class SearchActivity extends AbsBaseActivity {
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
setNavigationBarThemeColor();
|
||||||
protected boolean shouldColorStatusBar() {
|
setStatusBarThemeColor();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import com.kabouzeid.gramophone.prefs.ColorChooserPreference;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
@ -31,7 +30,6 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(!Util.isAtLeastLollipop());
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_preferences);
|
setContentView(R.layout.activity_preferences);
|
||||||
|
|
||||||
|
|
@ -42,16 +40,10 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
|
|
||||||
if (savedInstanceState == null)
|
if (savedInstanceState == null)
|
||||||
getFragmentManager().beginTransaction().replace(R.id.content_frame, new SettingsFragment()).commit();
|
getFragmentManager().beginTransaction().replace(R.id.content_frame, new SettingsFragment()).commit();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarOtherScreensEnabled())
|
||||||
protected boolean shouldColorStatusBar() {
|
setNavigationBarThemeColor();
|
||||||
return true;
|
setStatusBarThemeColor();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return PreferenceUtils.getInstance(this).coloredNavigationBarOtherScreensEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -121,14 +113,6 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
findPreference("transparent_toolbar").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
|
||||||
App.bus.post(new UIPreferenceChangedEvent(UIPreferenceChangedEvent.TOOLBAR_TRANSPARENT_CHANGED, o));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
findPreference("colored_album_footers").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
findPreference("colored_album_footers").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||||
|
|
@ -137,14 +121,6 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
findPreference("playback_controller_card").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
|
||||||
App.bus.post(new UIPreferenceChangedEvent(UIPreferenceChangedEvent.PLAYBACK_CONTROLLER_CARD_CHANGED, o));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Preference colorNavBar = findPreference("colored_navigation_bar");
|
Preference colorNavBar = findPreference("colored_navigation_bar");
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
colorNavBar.setEnabled(false);
|
colorNavBar.setEnabled(false);
|
||||||
|
|
@ -207,13 +183,16 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
||||||
super.onUIPreferenceChangedEvent(event);
|
super.onUIPreferenceChangedEvent(event);
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED:
|
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_OTHER_SCREENS_CHANGED:
|
||||||
setShouldColorNavBar((boolean) event.getValue());
|
if ((boolean) event.getValue()) setNavigationBarThemeColor();
|
||||||
|
else resetNavigationBarColor();
|
||||||
break;
|
break;
|
||||||
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_CHANGED:
|
case UIPreferenceChangedEvent.COLORED_NAVIGATION_BAR_CHANGED:
|
||||||
try {
|
try {
|
||||||
setShouldColorNavBar(((Set) event.getValue()).contains(PreferenceUtils.COLORED_NAVIGATION_BAR_OTHER_SCREENS));
|
if (((Set) event.getValue()).contains(PreferenceUtils.COLORED_NAVIGATION_BAR_OTHER_SCREENS))
|
||||||
|
setNavigationBarThemeColor();
|
||||||
|
else resetNavigationBarColor();
|
||||||
} catch (NullPointerException ignored) {
|
} catch (NullPointerException ignored) {
|
||||||
setShouldColorNavBar(false);
|
resetNavigationBarColor();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities.base;
|
package com.kabouzeid.gramophone.ui.activities.base;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
import com.crashlytics.android.Crashlytics;
|
||||||
|
|
@ -65,7 +63,7 @@ public abstract class AbsBaseActivity extends ThemeBaseActivity implements KabVi
|
||||||
return areViewsEnabled;
|
return areViewsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
protected void onUIPreferenceChangedEvent(UIPreferenceChangedEvent event) {
|
protected void onUIPreferenceChangedEvent(UIPreferenceChangedEvent event) {
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
case UIPreferenceChangedEvent.THEME_CHANGED:
|
case UIPreferenceChangedEvent.THEME_CHANGED:
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.kabouzeid.gramophone.ui.activities.base;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.util.Pair;
|
import android.support.v4.util.Pair;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
|
|
@ -13,14 +14,13 @@ import android.widget.Toast;
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.dialogs.ColorChooserDialog;
|
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
import com.kabouzeid.gramophone.misc.SmallOnGestureListener;
|
import com.kabouzeid.gramophone.misc.SmallOnGestureListener;
|
||||||
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
|
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
|
||||||
import com.melnykov.fab.FloatingActionButton;
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,15 +55,10 @@ public abstract class AbsFabActivity extends AbsBaseActivity {
|
||||||
|
|
||||||
getFab().setImageDrawable(playPauseDrawable);
|
getFab().setImageDrawable(playPauseDrawable);
|
||||||
final int accentColor = ThemeSingleton.get().positiveColor;
|
final int accentColor = ThemeSingleton.get().positiveColor;
|
||||||
|
getFab().setBackgroundTintList(Util.getEmptyColorStateList(accentColor));
|
||||||
if (accentColor == Color.WHITE) {
|
if (accentColor == Color.WHITE) {
|
||||||
getFab().setColorNormal(accentColor);
|
|
||||||
getFab().setColorPressed(ColorChooserDialog.shiftColorDown(accentColor));
|
|
||||||
getFab().setColorRipple(ColorChooserDialog.shiftColorUp(accentColor));
|
|
||||||
getFab().getDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
getFab().getDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||||
} else {
|
} else {
|
||||||
getFab().setColorNormal(accentColor);
|
|
||||||
getFab().setColorPressed(ColorChooserDialog.shiftColorUp(accentColor));
|
|
||||||
getFab().setColorRipple(ColorChooserDialog.shiftColorDown(accentColor));
|
|
||||||
getFab().getDrawable().clearColorFilter();
|
getFab().getDrawable().clearColorFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +108,7 @@ public abstract class AbsFabActivity extends AbsBaseActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFabState() {
|
protected void updateFabState() {
|
||||||
if (MusicPlayerRemote.isPlaying()) {
|
if (MusicPlayerRemote.isPlaying()) {
|
||||||
playPauseDrawable.setPause();
|
playPauseDrawable.setPause();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -135,10 +130,6 @@ public abstract class AbsFabActivity extends AbsBaseActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
updateControllerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateControllerState() {
|
|
||||||
updateFabState();
|
updateFabState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,4 +181,8 @@ public abstract class AbsFabActivity extends AbsBaseActivity {
|
||||||
private void setFabPause() {
|
private void setFabPause() {
|
||||||
playPauseDrawable.animatedPause();
|
playPauseDrawable.animatedPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setFabColor() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,26 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities.base;
|
package com.kabouzeid.gramophone.ui.activities.base;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.readystatesoftware.systembartint.SystemBarTintManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Aidan Follestad (afollestad)
|
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* READ!
|
|
||||||
* <p/>
|
|
||||||
* Instructions:
|
|
||||||
* <p/>
|
|
||||||
* KitKat or Lollipop solid statusBar with the right color (primaryDark):
|
|
||||||
* - shouldColorStatusBar return true OR return false and call setStatusBarColor() in the activity with a custom color
|
|
||||||
* - setStatusBarTranslucent(!Util.isAtLeastLollipop())
|
|
||||||
* <p/>
|
|
||||||
* KitKat or Lollipop translucent statusBar (not the color is too dark on Lollipop and KitKat only does fading but MUCH better performance the setStatusBarColor in onScrollCallback)
|
|
||||||
* - shouldColorStatusBar return false DO NOT return true and do not call setStatusBarColor() in this case at all here
|
|
||||||
* - setStatusBarTranslucent(true)
|
|
||||||
* - use a view below the statusBar to color it
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class ThemeBaseActivity extends AppCompatActivity implements KabViewsDisableAble {
|
public abstract class ThemeBaseActivity extends AppCompatActivity implements KabViewsDisableAble {
|
||||||
|
private int colorPrimary;
|
||||||
// private boolean mLastDarkTheme;
|
private int colorPrimaryDarker;
|
||||||
// private int mLastPrimary;
|
private int colorAccent;
|
||||||
// private int mLastAccent;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
@ -47,23 +29,16 @@ public abstract class ThemeBaseActivity extends AppCompatActivity implements Kab
|
||||||
setupTheme();
|
setupTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void setupTheme() {
|
private void setupTheme() {
|
||||||
// Apply colors to system UI if necessary
|
colorPrimary = PreferenceUtils.getInstance(this).getThemeColorPrimary();
|
||||||
setShouldColorNavBar(shouldColorNavBar());
|
colorPrimaryDarker = Util.shiftColorDown(colorPrimary);
|
||||||
setShouldColorStatusBar(shouldColorStatusBar());
|
colorAccent = PreferenceUtils.getInstance(this).getThemeColorAccent();
|
||||||
|
|
||||||
// Persist current values so the Activity knows if they change
|
ThemeSingleton.get().positiveColor = colorAccent;
|
||||||
// mLastDarkTheme = PreferenceUtils.getInstance(this).getGeneralTheme() == 1;
|
|
||||||
// mLastPrimary = PreferenceUtils.getInstance(this).getThemeColorPrimary();
|
|
||||||
// mLastAccent = PreferenceUtils.getInstance(this).getThemeColorAccent();
|
|
||||||
|
|
||||||
// Accent colors in dialogs, and any dynamic views that pull from this singleton
|
|
||||||
ThemeSingleton.get().positiveColor = PreferenceUtils.getInstance(this).getThemeColorAccent();
|
|
||||||
ThemeSingleton.get().negativeColor = ThemeSingleton.get().positiveColor;
|
ThemeSingleton.get().negativeColor = ThemeSingleton.get().positiveColor;
|
||||||
ThemeSingleton.get().neutralColor = ThemeSingleton.get().positiveColor;
|
ThemeSingleton.get().neutralColor = ThemeSingleton.get().positiveColor;
|
||||||
ThemeSingleton.get().widgetColor = ThemeSingleton.get().positiveColor;
|
ThemeSingleton.get().widgetColor = ThemeSingleton.get().positiveColor;
|
||||||
// Dark theme
|
|
||||||
ThemeSingleton.get().darkTheme = PreferenceUtils.getInstance(this).getGeneralTheme() == R.style.Theme_MaterialMusic;
|
ThemeSingleton.get().darkTheme = PreferenceUtils.getInstance(this).getGeneralTheme() == R.style.Theme_MaterialMusic;
|
||||||
|
|
||||||
if (!overridesTaskColor()) {
|
if (!overridesTaskColor()) {
|
||||||
|
|
@ -71,10 +46,6 @@ public abstract class ThemeBaseActivity extends AppCompatActivity implements Kab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean overridesTaskColor() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void notifyTaskColorChange(int color) {
|
protected void notifyTaskColorChange(int color) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
// Sets color of entry in the system recents page
|
// Sets color of entry in the system recents page
|
||||||
|
|
@ -86,62 +57,58 @@ public abstract class ThemeBaseActivity extends AppCompatActivity implements Kab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
public int getThemeColorPrimary() {
|
||||||
// protected void onResume() {
|
return colorPrimary;
|
||||||
// super.onResume();
|
}
|
||||||
// if (mLastDarkTheme != (PreferenceUtils.getInstance(this).getGeneralTheme() == 1) ||
|
|
||||||
// mLastPrimary != PreferenceUtils.getInstance(this).getThemeColorPrimary() ||
|
|
||||||
// mLastAccent != PreferenceUtils.getInstance(this).getThemeColorAccent()) {
|
|
||||||
// // Theme colors changed, recreate the Activity
|
|
||||||
// recreate();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected void setStatusBarTranslucent(boolean statusBarTranslucent) {
|
public int getThemeColorPrimaryDarker() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
return colorPrimaryDarker;
|
||||||
Util.setStatusBarTranslucent(getWindow(), statusBarTranslucent);
|
}
|
||||||
|
|
||||||
|
public int getThemeColorAccent() {
|
||||||
|
return colorAccent;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setStatusBarTransparent() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
Util.setAllowDrawUnderStatusBar(getWindow());
|
||||||
|
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||||
|
Util.setStatusBarTranslucent(getWindow(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void setNavigationBarColor(int color) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
getWindow().setNavigationBarColor(Util.shiftColorDown(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void setStatusBarColor(int color) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
getWindow().setStatusBarColor(Util.shiftColorDown(color));
|
||||||
|
else 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract boolean shouldColorStatusBar();
|
protected final void setNavigationBarThemeColor() {
|
||||||
|
setNavigationBarColor(colorPrimary);
|
||||||
protected abstract boolean shouldColorNavBar();
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
protected final void setStatusBarColor(int color, boolean forceSystemBarTint) {
|
|
||||||
if (!forceSystemBarTint && Util.isAtLeastLollipop()) {
|
|
||||||
getWindow().setStatusBarColor(color);
|
|
||||||
} else {
|
|
||||||
SystemBarTintManager tintManager = new SystemBarTintManager(this);
|
|
||||||
tintManager.setStatusBarTintEnabled(true);
|
|
||||||
tintManager.setStatusBarTintColor(color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
protected final void setStatusBarThemeColor() {
|
||||||
protected final void setShouldColorNavBar(boolean shouldColorNavBar) {
|
setStatusBarColor(colorPrimary);
|
||||||
if (Util.isAtLeastLollipop()) {
|
|
||||||
if (shouldColorNavBar) {
|
|
||||||
final int primaryDark = PreferenceUtils.getInstance(this).getThemeColorPrimaryDarker();
|
|
||||||
getWindow().setNavigationBarColor(primaryDark);
|
|
||||||
} else {
|
|
||||||
getWindow().setNavigationBarColor(Color.BLACK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
protected final void resetNavigationBarColor() {
|
||||||
protected final void setShouldColorStatusBar(boolean shouldColorStatusBar) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
if (shouldColorStatusBar) {
|
setNavigationBarColor(Util.resolveColor(this, android.R.attr.navigationBarColor));
|
||||||
final int primaryDark = PreferenceUtils.getInstance(this).getThemeColorPrimaryDarker();
|
}
|
||||||
setStatusBarColor(primaryDark, false);
|
|
||||||
} else {
|
protected final void resetStatusBarColor() {
|
||||||
if (Util.isAtLeastLollipop()) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
getWindow().setStatusBarColor(Util.resolveColor(this, android.R.attr.statusBarColor));
|
setStatusBarColor(Util.resolveColor(this, android.R.attr.statusBarColor));
|
||||||
} else {
|
}
|
||||||
SystemBarTintManager tintManager = new SystemBarTintManager(this);
|
|
||||||
tintManager.setStatusBarTintEnabled(false);
|
protected boolean overridesTaskColor() {
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
|
@ -10,6 +9,7 @@ import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.graphics.Palette;
|
import android.support.v7.graphics.Palette;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
@ -19,11 +19,11 @@ import android.view.animation.OvershootInterpolator;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.afollestad.materialdialogs.util.DialogUtils;
|
import com.afollestad.materialdialogs.util.DialogUtils;
|
||||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.dialogs.ColorChooserDialog;
|
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
|
|
@ -32,7 +32,6 @@ import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
import com.kabouzeid.gramophone.util.PreferenceUtils;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
import com.melnykov.fab.FloatingActionButton;
|
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
import com.nineoldandroids.view.ViewHelper;
|
||||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
@ -90,7 +89,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
setStatusBarTranslucent(!Util.isAtLeastLollipop());
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(getContentViewResId());
|
setContentView(getContentViewResId());
|
||||||
|
|
||||||
|
|
@ -113,16 +111,6 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorStatusBar() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldColorNavBar() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
fab = (FloatingActionButton) findViewById(R.id.fab);
|
fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||||
scrollView = (ObservableScrollView) findViewById(R.id.observableScrollView);
|
scrollView = (ObservableScrollView) findViewById(R.id.observableScrollView);
|
||||||
|
|
@ -203,18 +191,19 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
fab.setRippleColor(ThemeSingleton.get().positiveColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void save();
|
protected abstract void save();
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private void resetColors() {
|
private void resetColors() {
|
||||||
final int primaryColor = PreferenceUtils.getInstance(this).getThemeColorPrimary();
|
final int primaryColor = PreferenceUtils.getInstance(this).getThemeColorPrimary();
|
||||||
paletteColorPrimary = primaryColor;
|
paletteColorPrimary = primaryColor;
|
||||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||||
setStatusBarColor(ColorChooserDialog.shiftColorDown(primaryColor), false);
|
setStatusBarColor(primaryColor);
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarTagEditorEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarTagEditorEnabled())
|
||||||
getWindow().setNavigationBarColor(primaryColor);
|
setNavigationBarColor(primaryColor);
|
||||||
notifyTaskColorChange(primaryColor);
|
notifyTaskColorChange(primaryColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +240,7 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
protected void setNoImageMode() {
|
protected void setNoImageMode() {
|
||||||
isInNoImageMode = true;
|
isInNoImageMode = true;
|
||||||
image.setVisibility(View.GONE);
|
image.setVisibility(View.GONE);
|
||||||
|
|
@ -264,10 +253,9 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
toolBar.setBackgroundColor(paletteColorPrimary);
|
toolBar.setBackgroundColor(paletteColorPrimary);
|
||||||
header.setBackgroundColor(paletteColorPrimary);
|
header.setBackgroundColor(paletteColorPrimary);
|
||||||
|
|
||||||
int primaryDark = ColorChooserDialog.shiftColorDown(paletteColorPrimary);
|
setStatusBarColor(paletteColorPrimary);
|
||||||
setStatusBarColor(primaryDark, false);
|
if (PreferenceUtils.getInstance(this).coloredNavigationBarTagEditorEnabled())
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarTagEditorEnabled())
|
setNavigationBarColor(paletteColorPrimary);
|
||||||
getWindow().setNavigationBarColor(primaryDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void dataChanged() {
|
protected void dataChanged() {
|
||||||
|
|
@ -301,7 +289,7 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
private void applyPalette(final Bitmap bitmap) {
|
private void applyPalette(final Bitmap bitmap) {
|
||||||
Palette.from(bitmap)
|
Palette.from(bitmap)
|
||||||
.generate(new Palette.PaletteAsyncListener() {
|
.generate(new Palette.PaletteAsyncListener() {
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerated(Palette palette) {
|
public void onGenerated(Palette palette) {
|
||||||
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
|
||||||
|
|
@ -309,9 +297,9 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||||
final int vibrantColor = palette.getVibrantColor(DialogUtils.resolveColor(AbsTagEditorActivity.this, R.attr.default_bar_color));
|
final int vibrantColor = palette.getVibrantColor(DialogUtils.resolveColor(AbsTagEditorActivity.this, R.attr.default_bar_color));
|
||||||
paletteColorPrimary = vibrantColor;
|
paletteColorPrimary = vibrantColor;
|
||||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||||
setStatusBarColor(ColorChooserDialog.shiftColorDown(vibrantColor), false);
|
setStatusBarColor(vibrantColor);
|
||||||
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(AbsTagEditorActivity.this).coloredNavigationBarTagEditorEnabled())
|
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(AbsTagEditorActivity.this).coloredNavigationBarTagEditorEnabled())
|
||||||
getWindow().setNavigationBarColor(vibrantColor);
|
setNavigationBarColor(vibrantColor);
|
||||||
notifyTaskColorChange(vibrantColor);
|
notifyTaskColorChange(vibrantColor);
|
||||||
} else {
|
} else {
|
||||||
resetColors();
|
resetColors();
|
||||||
|
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.ui.fragments;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.support.v4.view.GravityCompat;
|
|
||||||
import android.support.v4.widget.DrawerLayout;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
|
||||||
import com.kabouzeid.gramophone.adapter.NavigationDrawerItemAdapter;
|
|
||||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
|
||||||
import com.kabouzeid.gramophone.model.NavigationDrawerItem;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class NavigationDrawerFragment extends Fragment {
|
|
||||||
|
|
||||||
public static final int NAVIGATION_DRAWER_HEADER = -1;
|
|
||||||
public static final int ABOUT_INDEX = 5;
|
|
||||||
public static final int SETTINGS_INDEX = 4;
|
|
||||||
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
|
|
||||||
|
|
||||||
public View fragmentRootView;
|
|
||||||
private NavigationDrawerCallbacks callbacks;
|
|
||||||
private NavigationDrawerItemAdapter drawerAdapter;
|
|
||||||
private DrawerLayout drawerLayout;
|
|
||||||
private RecyclerView drawerRecyclerView;
|
|
||||||
|
|
||||||
private Button headerButton;
|
|
||||||
private ImageView albumArt;
|
|
||||||
private TextView songTitle;
|
|
||||||
private TextView songArtist;
|
|
||||||
|
|
||||||
private boolean fromSavedInstanceState;
|
|
||||||
private boolean userLearnedDrawer;
|
|
||||||
|
|
||||||
private int checkedPosition = 0;
|
|
||||||
|
|
||||||
public NavigationDrawerFragment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDrawerOpen() {
|
|
||||||
return drawerLayout != null && drawerLayout.isDrawerOpen(Gravity.START);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUp(final DrawerLayout drawerLayout) {
|
|
||||||
this.drawerLayout = drawerLayout;
|
|
||||||
this.drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
|
||||||
|
|
||||||
if (!userLearnedDrawer && !fromSavedInstanceState) {
|
|
||||||
this.drawerLayout.openDrawer(Gravity.START);
|
|
||||||
userLearnedDrawer = true;
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putBoolean(AppKeys.SP_USER_LEARNED_DRAWER, true).apply();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextView getSongArtist() {
|
|
||||||
return songArtist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImageView getAlbumArtImageView() {
|
|
||||||
return albumArt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextView getSongTitle() {
|
|
||||||
return songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
try {
|
|
||||||
callbacks = (NavigationDrawerCallbacks) activity;
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
userLearnedDrawer = PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean(AppKeys.SP_USER_LEARNED_DRAWER, false);
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
setItemChecked(savedInstanceState.getInt(STATE_SELECTED_POSITION));
|
|
||||||
fromSavedInstanceState = true;
|
|
||||||
}
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
return inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
|
||||||
fragmentRootView = view;
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
initViews();
|
|
||||||
setUpViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
|
||||||
drawerRecyclerView = (RecyclerView) fragmentRootView.findViewById(R.id.navigation_drawer_list);
|
|
||||||
final View drawerHeader = fragmentRootView.findViewById(R.id.header);
|
|
||||||
headerButton = (Button) drawerHeader.findViewById(R.id.header_clickable);
|
|
||||||
albumArt = (ImageView) drawerHeader.findViewById(R.id.album_art);
|
|
||||||
songTitle = (TextView) drawerHeader.findViewById(R.id.song_title);
|
|
||||||
songArtist = (TextView) drawerHeader.findViewById(R.id.song_artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpViews() {
|
|
||||||
headerButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
selectItem(NAVIGATION_DRAWER_HEADER);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setUpListView();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpListView() {
|
|
||||||
final ArrayList<NavigationDrawerItem> navigationDrawerItems = new ArrayList<>();
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.songs), R.drawable.ic_audiotrack_white_24dp));
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.albums), R.drawable.ic_album_white_24dp));
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.artists), R.drawable.ic_person_white_24dp));
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.playlists), R.drawable.ic_queue_music_white_24dp));
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.action_settings), R.drawable.ic_settings_white_24dp));
|
|
||||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.action_about), R.drawable.ic_help_white_24dp));
|
|
||||||
|
|
||||||
drawerAdapter = new NavigationDrawerItemAdapter(getActivity(), navigationDrawerItems, new NavigationDrawerItemAdapter.Callback() {
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(int index) {
|
|
||||||
selectItem(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
drawerRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
||||||
drawerRecyclerView.setAdapter(drawerAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectItem(final int position) {
|
|
||||||
if (position != NAVIGATION_DRAWER_HEADER &&
|
|
||||||
position != ABOUT_INDEX && position != SETTINGS_INDEX) {
|
|
||||||
setItemChecked(position);
|
|
||||||
if (drawerLayout != null)
|
|
||||||
drawerLayout.closeDrawers();
|
|
||||||
}
|
|
||||||
if (callbacks != null)
|
|
||||||
callbacks.onNavigationDrawerItemSelected(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putInt(STATE_SELECTED_POSITION, checkedPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
super.onDetach();
|
|
||||||
callbacks = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setItemChecked(final int position) {
|
|
||||||
if (drawerAdapter != null) {
|
|
||||||
drawerAdapter.setChecked(position);
|
|
||||||
checkedPosition = position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface NavigationDrawerCallbacks {
|
|
||||||
void onNavigationDrawerItemSelected(int position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,7 @@ import android.support.v4.app.Fragment;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.ui.activities.MainActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
|
@ -14,19 +14,15 @@ public abstract class AbsMainActivityFragment extends Fragment implements KabVie
|
||||||
private boolean areViewsEnabled;
|
private boolean areViewsEnabled;
|
||||||
|
|
||||||
protected int getTopPadding() {
|
protected int getTopPadding() {
|
||||||
final int norm = Util.getActionBarSize(getActivity()) +
|
return getResources().getDimensionPixelSize(R.dimen.list_padding_vertical);
|
||||||
getResources().getDimensionPixelSize(R.dimen.tab_height) +
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.list_padding_vertical);
|
|
||||||
if (Util.isAtLeastKitKat() && !Util.isAtLeastLollipop()) {
|
|
||||||
if (Util.isInPortraitMode(getActivity()) || Util.isTablet(getActivity())) {
|
|
||||||
return norm + Util.getStatusBarHeight(getActivity());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return norm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getBottomPadding() {
|
protected int getBottomPadding() {
|
||||||
return 0;
|
return getResources().getDimensionPixelSize(R.dimen.bottom_offset_fab_activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MainActivity getMainActivity() {
|
||||||
|
return (MainActivity) getActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class AlbumViewFragment extends AbsMainActivityRecyclerViewFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RecyclerView.Adapter createAdapter() {
|
protected RecyclerView.Adapter createAdapter() {
|
||||||
return new AlbumAdapter(getActivity());
|
return new AlbumAdapter(getMainActivity(), getMainActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColumns(int columns) {
|
public void setColumns(int columns) {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,6 @@ public class ArtistViewFragment extends AbsMainActivityRecyclerViewFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RecyclerView.Adapter createAdapter() {
|
protected RecyclerView.Adapter createAdapter() {
|
||||||
return new ArtistAdapter(getActivity());
|
return new ArtistAdapter(getMainActivity(), getMainActivity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||||
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
@ -41,7 +40,7 @@ public class PlaylistViewFragment extends AbsMainActivityRecyclerViewFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RecyclerView.Adapter createAdapter() {
|
protected RecyclerView.Adapter createAdapter() {
|
||||||
PlaylistAdapter adapter = new PlaylistAdapter((AppCompatActivity) getActivity());
|
PlaylistAdapter adapter = new PlaylistAdapter(getMainActivity(), getMainActivity());
|
||||||
View v = getView();
|
View v = getView();
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
v.findViewById(android.R.id.empty).setVisibility(
|
v.findViewById(android.R.id.empty).setVisibility(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||||
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
import android.support.v7.widget.GridLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
|
||||||
|
|
@ -26,6 +25,6 @@ public class SongViewFragment extends AbsMainActivityRecyclerViewFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RecyclerView.Adapter createAdapter() {
|
protected RecyclerView.Adapter createAdapter() {
|
||||||
return new SongAdapter((AppCompatActivity) getActivity());
|
return new SongAdapter(getMainActivity(), getMainActivity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ import android.widget.Toast;
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
|
||||||
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
import com.kabouzeid.gramophone.model.PlaylistSong;
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,13 +61,26 @@ public class PlaylistsUtil {
|
||||||
// context.getContentResolver().delete(uri, null, null);
|
// context.getContentResolver().delete(uri, null, null);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public static void deletePlaylist(final Context context, final long playlistId) {
|
public static void deletePlaylists(final Context context, final long playlistId) {
|
||||||
final Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
final Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||||
String where = MediaStore.Audio.Playlists._ID + "=?";
|
String where = MediaStore.Audio.Playlists._ID + "=?";
|
||||||
String[] whereVal = {String.valueOf(playlistId)};
|
String[] whereVal = {String.valueOf(playlistId)};
|
||||||
context.getContentResolver().delete(uri, where, whereVal);
|
context.getContentResolver().delete(uri, where, whereVal);
|
||||||
Toast.makeText(context, context.getResources().getString(R.string.deleted_playlist_x,
|
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||||
getNameForPlaylist(context, playlistId)), Toast.LENGTH_SHORT).show();
|
}
|
||||||
|
|
||||||
|
public static void deletePlaylists(final Context context, final ArrayList<Playlist> playlists) {
|
||||||
|
final Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||||
|
final StringBuilder selection = new StringBuilder();
|
||||||
|
selection.append(MediaStore.Audio.Playlists._ID + " IN (");
|
||||||
|
for (int i = 0; i < playlists.size(); i++) {
|
||||||
|
selection.append(playlists.get(i).id);
|
||||||
|
if (i < playlists.size() - 1) {
|
||||||
|
selection.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selection.append(")");
|
||||||
|
context.getContentResolver().delete(uri, selection.toString(), null);
|
||||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,20 +146,20 @@ public class PlaylistsUtil {
|
||||||
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static void removeFromPlaylist(final Context context, final List<PlaylistSong> songs) {
|
public static void removeFromPlaylist(final Context context, final List<PlaylistSong> songs) {
|
||||||
// Uri uri = MediaStore.Audio.Playlists.Members.getContentUri(
|
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri(
|
||||||
// "external", songs.get(0).playlistId);
|
"external", songs.get(0).playlistId);
|
||||||
// String selectionArgs[] = new String[songs.size()];
|
String selectionArgs[] = new String[songs.size()];
|
||||||
// for (int i = 0; i < selectionArgs.length; i++) {
|
for (int i = 0; i < selectionArgs.length; i++) {
|
||||||
// selectionArgs[i] = String.valueOf(songs.get(i).idInPlayList);
|
selectionArgs[i] = String.valueOf(songs.get(i).idInPlayList);
|
||||||
// }
|
}
|
||||||
// String selection = MediaStore.Audio.Playlists.Members._ID + " in (";
|
String selection = MediaStore.Audio.Playlists.Members._ID + " in (";
|
||||||
// for (String selectionArg : selectionArgs) selection += "?, ";
|
for (String selectionArg : selectionArgs) selection += "?, ";
|
||||||
// selection = selection.substring(0, selection.length() - 2) + ")";
|
selection = selection.substring(0, selection.length() - 2) + ")";
|
||||||
//
|
|
||||||
// context.getContentResolver().delete(uri, selection, selectionArgs);
|
context.getContentResolver().delete(uri, selection, selectionArgs);
|
||||||
// App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
App.bus.post(new DataBaseChangedEvent(DataBaseChangedEvent.PLAYLISTS_CHANGED));
|
||||||
// }
|
}
|
||||||
//
|
//
|
||||||
// public static int getSongCountForPlaylist(final Context context, final long playlistId) {
|
// public static int getSongCountForPlaylist(final Context context, final long playlistId) {
|
||||||
// Cursor c = context.getContentResolver().query(
|
// Cursor c = context.getContentResolver().query(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.dialogs.ColorChooserDialog;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -23,7 +22,7 @@ public final class PreferenceUtils {
|
||||||
public static final String ALBUM_SORT_ORDER = "album_sort_order";
|
public static final String ALBUM_SORT_ORDER = "album_sort_order";
|
||||||
public static final String ALBUM_SONG_SORT_ORDER = "album_song_sort_order";
|
public static final String ALBUM_SONG_SORT_ORDER = "album_song_sort_order";
|
||||||
public static final String SONG_SORT_ORDER = "song_sort_order";
|
public static final String SONG_SORT_ORDER = "song_sort_order";
|
||||||
public static final String ONLY_ON_WIFI = "auto_download_artist_images";
|
// public static final String ONLY_ON_WIFI = "auto_download_artist_images";
|
||||||
// public static final String DOWNLOAD_MISSING_ARTIST_IMAGES = "auto_download_artist_images";
|
// public static final String DOWNLOAD_MISSING_ARTIST_IMAGES = "auto_download_artist_images";
|
||||||
public static final String COLORED_ALBUM_FOOTERS = "colored_album_footers";
|
public static final String COLORED_ALBUM_FOOTERS = "colored_album_footers";
|
||||||
public static final String COLORED_NAVIGATION_BAR = "colored_navigation_bar";
|
public static final String COLORED_NAVIGATION_BAR = "colored_navigation_bar";
|
||||||
|
|
@ -33,10 +32,10 @@ public final class PreferenceUtils {
|
||||||
public static final String COLORED_NAVIGATION_BAR_PLAYIST = "colored_navigation_bar_playlist";
|
public static final String COLORED_NAVIGATION_BAR_PLAYIST = "colored_navigation_bar_playlist";
|
||||||
public static final String COLORED_NAVIGATION_BAR_TAG_EDITOR = "colored_navigation_bar_tag_editor";
|
public static final String COLORED_NAVIGATION_BAR_TAG_EDITOR = "colored_navigation_bar_tag_editor";
|
||||||
public static final String COLORED_NAVIGATION_BAR_OTHER_SCREENS = "colored_navigation_bar_other_screens";
|
public static final String COLORED_NAVIGATION_BAR_OTHER_SCREENS = "colored_navigation_bar_other_screens";
|
||||||
public static final String PLAYBACK_CONTROLLER_BOX = "playback_controller_card";
|
|
||||||
public static final String TRANSPARENT_TOOLBAR = "transparent_toolbar";
|
|
||||||
public static final String ALBUM_GRID_COLUMNS = "album_grid_columns";
|
public static final String ALBUM_GRID_COLUMNS = "album_grid_columns";
|
||||||
public static final String ALBUM_GRID_COLUMNS_LAND = "album_grid_columns_land";
|
public static final String ALBUM_GRID_COLUMNS_LAND = "album_grid_columns_land";
|
||||||
|
public static final String OPAQUE_TOOLBAR_NOW_PLAYING = "opaque_toolbar_now_playing";
|
||||||
|
public static final String FORCE_SQUARE_ALBUM_ART = "force_square_album_art";
|
||||||
|
|
||||||
private static PreferenceUtils sInstance;
|
private static PreferenceUtils sInstance;
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ public final class PreferenceUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getThemeColorPrimaryDarker() {
|
public int getThemeColorPrimaryDarker() {
|
||||||
return ColorChooserDialog.shiftColorDown(getThemeColorPrimary());
|
return Util.shiftColorDown(getThemeColorPrimary());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CommitPrefEdits")
|
@SuppressLint("CommitPrefEdits")
|
||||||
|
|
@ -80,7 +79,7 @@ public final class PreferenceUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getThemeColorAccent() {
|
public int getThemeColorAccent() {
|
||||||
return mPreferences.getInt("accent_color", mContext.getResources().getColor(R.color.pink_500));
|
return mPreferences.getInt("accent_color", mContext.getResources().getColor(R.color.pink_A200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CommitPrefEdits")
|
@SuppressLint("CommitPrefEdits")
|
||||||
|
|
@ -136,7 +135,7 @@ public final class PreferenceUtils {
|
||||||
|
|
||||||
@SuppressLint("CommitPrefEdits")
|
@SuppressLint("CommitPrefEdits")
|
||||||
private boolean coloredNavigationBarFor(String key) {
|
private boolean coloredNavigationBarFor(String key) {
|
||||||
Set<String> defaultVals = new HashSet<>();
|
final Set<String> defaultVals = new HashSet<>();
|
||||||
defaultVals.add(COLORED_NAVIGATION_BAR_ALBUM);
|
defaultVals.add(COLORED_NAVIGATION_BAR_ALBUM);
|
||||||
defaultVals.add(COLORED_NAVIGATION_BAR_ARTIST);
|
defaultVals.add(COLORED_NAVIGATION_BAR_ARTIST);
|
||||||
defaultVals.add(COLORED_NAVIGATION_BAR_CURRENT_PLAYING);
|
defaultVals.add(COLORED_NAVIGATION_BAR_CURRENT_PLAYING);
|
||||||
|
|
@ -148,6 +147,7 @@ public final class PreferenceUtils {
|
||||||
mPreferences.edit().putStringSet(COLORED_NAVIGATION_BAR, defaultVals).commit();
|
mPreferences.edit().putStringSet(COLORED_NAVIGATION_BAR, defaultVals).commit();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
//noinspection ConstantConditions
|
||||||
return mPreferences.getStringSet(COLORED_NAVIGATION_BAR, defaultVals).contains(key);
|
return mPreferences.getStringSet(COLORED_NAVIGATION_BAR, defaultVals).contains(key);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -159,12 +159,12 @@ public final class PreferenceUtils {
|
||||||
// mPreferences.edit().putBoolean(COLORED_NAVIGATION_BAR_OTHER_SCREENS, coloredNavbar).commit();
|
// mPreferences.edit().putBoolean(COLORED_NAVIGATION_BAR_OTHER_SCREENS, coloredNavbar).commit();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public final boolean playbackControllerBoxEnabled() {
|
public final boolean opaqueToolbarNowPlaying() {
|
||||||
return mPreferences.getBoolean(PLAYBACK_CONTROLLER_BOX, false);
|
return mPreferences.getBoolean(OPAQUE_TOOLBAR_NOW_PLAYING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean transparentToolbar() {
|
public final boolean forceAlbumArtSquared() {
|
||||||
return mPreferences.getBoolean(TRANSPARENT_TOOLBAR, false);
|
return mPreferences.getBoolean(FORCE_SQUARE_ALBUM_ART, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public final boolean downloadMissingArtistImages() {
|
// public final boolean downloadMissingArtistImages() {
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,14 @@ package com.kabouzeid.gramophone.util;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.DrawableRes;
|
import android.support.annotation.DrawableRes;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
@ -106,6 +109,12 @@ public class Util {
|
||||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setAllowDrawUnderStatusBar(Window window) {
|
||||||
|
window.getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
// public static boolean isOnline(final Context context) {
|
// public static boolean isOnline(final Context context) {
|
||||||
// if (context == null)
|
// if (context == null)
|
||||||
// return false;
|
// return false;
|
||||||
|
|
@ -201,4 +210,32 @@ public class Util {
|
||||||
}
|
}
|
||||||
return drawable;
|
return drawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getOpaqueColor(@ColorInt int color) {
|
||||||
|
return color | 0xFF000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getColorWithAlpha(float alpha, 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) {
|
||||||
|
int alpha = Color.alpha(color);
|
||||||
|
float[] hsv = new float[3];
|
||||||
|
Color.colorToHSV(color, hsv);
|
||||||
|
hsv[2] *= 0.9f; // value component
|
||||||
|
return (alpha << 24) + (0x00ffffff & Color.HSVToColor(hsv));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColorStateList getEmptyColorStateList(int color) {
|
||||||
|
return new ColorStateList(
|
||||||
|
new int[][]{
|
||||||
|
new int[]{}
|
||||||
|
},
|
||||||
|
new int[]{color}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,12 +13,15 @@ import android.widget.CheckBox;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.ThemeSingleton;
|
import com.afollestad.materialdialogs.ThemeSingleton;
|
||||||
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import hugo.weaving.DebugLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
|
|
@ -84,6 +87,22 @@ public class ViewUtil {
|
||||||
animator.start();
|
animator.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DebugLog
|
||||||
|
public static void animateTextColor(final TextView v, final int startColor, final int endColor) {
|
||||||
|
animateTextColor(v, startColor, endColor, DEFAULT_COLOR_ANIMATION_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void animateTextColor(final TextView v, final int startColor, final int endColor, final int duration) {
|
||||||
|
ObjectAnimator animator = ObjectAnimator.ofObject(v, "textColor",
|
||||||
|
new ArgbEvaluator(), startColor, endColor);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
animator.setInterpolator(new PathInterpolator(0.4f, 0f, 1f, 1f));
|
||||||
|
}
|
||||||
|
animator.setDuration(duration);
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
|
||||||
public static void setBackgroundAlpha(View view, float alpha, int baseColor) {
|
public static void setBackgroundAlpha(View view, float alpha, int baseColor) {
|
||||||
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24;
|
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24;
|
||||||
int rgb = 0x00ffffff & baseColor;
|
int rgb = 0x00ffffff & baseColor;
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ import android.util.AttributeSet;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
|
|
||||||
public class CircleView extends FrameLayout {
|
public class ColorView extends FrameLayout {
|
||||||
|
|
||||||
private final Bitmap mCheck;
|
private final Bitmap mCheck;
|
||||||
private final Paint paint;
|
private final Paint paint;
|
||||||
|
|
@ -22,19 +23,19 @@ public class CircleView extends FrameLayout {
|
||||||
private Paint paintCheck;
|
private Paint paintCheck;
|
||||||
private final int borderWidth;
|
private final int borderWidth;
|
||||||
|
|
||||||
public CircleView(Context context) {
|
public ColorView(Context context) {
|
||||||
this(context, null, 0);
|
this(context, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CircleView(Context context, AttributeSet attrs) {
|
public ColorView(Context context, AttributeSet attrs) {
|
||||||
this(context, attrs, 0);
|
this(context, attrs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public ColorView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
final int checkSize = (int) context.getResources().getDimension(R.dimen.circle_view_check);
|
final int checkSize = (int) context.getResources().getDimension(R.dimen.circle_view_check);
|
||||||
mCheck = getResizedBitmap(BitmapFactory.decodeResource(context.getResources(),
|
mCheck = getResizedBitmap(BitmapFactory.decodeResource(context.getResources(),
|
||||||
R.drawable.ic_check_white_24dp), checkSize, checkSize);
|
R.drawable.ic_checkbox_marked_circle_outline_white_24dp), checkSize, checkSize);
|
||||||
borderWidth = (int) getResources().getDimension(R.dimen.circle_view_border);
|
borderWidth = (int) getResources().getDimension(R.dimen.circle_view_border);
|
||||||
|
|
||||||
paint = new Paint();
|
paint = new Paint();
|
||||||
|
|
@ -42,7 +43,6 @@ public class CircleView extends FrameLayout {
|
||||||
|
|
||||||
paintBorder = new Paint();
|
paintBorder = new Paint();
|
||||||
paintBorder.setAntiAlias(true);
|
paintBorder.setAntiAlias(true);
|
||||||
paintBorder.setColor(Color.BLACK);
|
|
||||||
|
|
||||||
setWillNotDraw(false);
|
setWillNotDraw(false);
|
||||||
}
|
}
|
||||||
|
|
@ -64,12 +64,7 @@ public class CircleView extends FrameLayout {
|
||||||
@Override
|
@Override
|
||||||
public void setBackgroundColor(int color) {
|
public void setBackgroundColor(int color) {
|
||||||
paint.setColor(color);
|
paint.setColor(color);
|
||||||
requestLayout();
|
paintBorder.setColor(Util.shiftColorDown(color));
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBorderColor(int color) {
|
|
||||||
paintBorder.setColor(color);
|
|
||||||
requestLayout();
|
requestLayout();
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.kabouzeid.gramophone.views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class HeightFitSquareImageView extends ImageView {
|
||||||
|
|
||||||
|
public HeightFitSquareImageView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeightFitSquareImageView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeightFitSquareImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
//noinspection SuspiciousNameCombination
|
||||||
|
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.kabouzeid.gramophone.views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class HeightWidthFitSquareImageView extends ImageView {
|
||||||
|
|
||||||
|
public HeightWidthFitSquareImageView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeightWidthFitSquareImageView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeightWidthFitSquareImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
final int small = Math.min(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
super.onMeasure(small, small);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -44,8 +44,6 @@ public class PlayPauseDrawable extends Drawable {
|
||||||
|
|
||||||
private float width;
|
private float width;
|
||||||
private float height;
|
private float height;
|
||||||
private final float fallBackWidth;
|
|
||||||
private final float fallBackHeight;
|
|
||||||
|
|
||||||
private float progress;
|
private float progress;
|
||||||
private boolean isPlay;
|
private boolean isPlay;
|
||||||
|
|
@ -61,8 +59,6 @@ public class PlayPauseDrawable extends Drawable {
|
||||||
pauseBarWidth = res.getDimensionPixelSize(R.dimen.pause_bar_width);
|
pauseBarWidth = res.getDimensionPixelSize(R.dimen.pause_bar_width);
|
||||||
pauseBarHeight = res.getDimensionPixelSize(R.dimen.pause_bar_height);
|
pauseBarHeight = res.getDimensionPixelSize(R.dimen.pause_bar_height);
|
||||||
pauseBarDistance = res.getDimensionPixelSize(R.dimen.pause_bar_distance);
|
pauseBarDistance = res.getDimensionPixelSize(R.dimen.pause_bar_distance);
|
||||||
fallBackWidth = res.getDimensionPixelSize(R.dimen.fab_icon_bound_width);
|
|
||||||
fallBackHeight = res.getDimensionPixelSize(R.dimen.fab_icon_bound_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -71,9 +67,6 @@ public class PlayPauseDrawable extends Drawable {
|
||||||
if (bounds.width() > 0 && bounds.height() > 0) {
|
if (bounds.width() > 0 && bounds.height() > 0) {
|
||||||
width = bounds.width();
|
width = bounds.width();
|
||||||
height = bounds.height();
|
height = bounds.height();
|
||||||
} else {
|
|
||||||
width = fallBackWidth;
|
|
||||||
height = fallBackHeight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.views;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.support.v4.view.ViewCompat;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
|
|
||||||
* (status and navigation bars, overlay action bars).
|
|
||||||
*/
|
|
||||||
public class ScrimInsetsFrameLayout extends FrameLayout {
|
|
||||||
private Drawable mInsetForeground;
|
|
||||||
|
|
||||||
private Rect mInsets;
|
|
||||||
private Rect mTempRect = new Rect();
|
|
||||||
private OnInsetsCallback mOnInsetsCallback;
|
|
||||||
|
|
||||||
public ScrimInsetsFrameLayout(Context context) {
|
|
||||||
super(context);
|
|
||||||
init(context, null, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init(context, attrs, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
init(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
|
||||||
R.styleable.ScrimInsetsView, defStyle, 0);
|
|
||||||
if (a == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
|
|
||||||
a.recycle();
|
|
||||||
|
|
||||||
setWillNotDraw(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean fitSystemWindows(Rect insets) {
|
|
||||||
mInsets = new Rect(insets);
|
|
||||||
setWillNotDraw(mInsetForeground == null);
|
|
||||||
ViewCompat.postInvalidateOnAnimation(this);
|
|
||||||
if (mOnInsetsCallback != null) {
|
|
||||||
mOnInsetsCallback.onInsetsChanged(insets);
|
|
||||||
}
|
|
||||||
return true; // consume insets
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
super.draw(canvas);
|
|
||||||
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
if (mInsets != null && mInsetForeground != null) {
|
|
||||||
int sc = canvas.save();
|
|
||||||
canvas.translate(getScrollX(), getScrollY());
|
|
||||||
|
|
||||||
// Top
|
|
||||||
mTempRect.set(0, 0, width, mInsets.top);
|
|
||||||
mInsetForeground.setBounds(mTempRect);
|
|
||||||
mInsetForeground.draw(canvas);
|
|
||||||
|
|
||||||
// Bottom
|
|
||||||
mTempRect.set(0, height - mInsets.bottom, width, height);
|
|
||||||
mInsetForeground.setBounds(mTempRect);
|
|
||||||
mInsetForeground.draw(canvas);
|
|
||||||
|
|
||||||
// Left
|
|
||||||
mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
|
|
||||||
mInsetForeground.setBounds(mTempRect);
|
|
||||||
mInsetForeground.draw(canvas);
|
|
||||||
|
|
||||||
// Right
|
|
||||||
mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
|
|
||||||
mInsetForeground.setBounds(mTempRect);
|
|
||||||
mInsetForeground.draw(canvas);
|
|
||||||
|
|
||||||
canvas.restoreToCount(sc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAttachedToWindow() {
|
|
||||||
super.onAttachedToWindow();
|
|
||||||
if (mInsetForeground != null) {
|
|
||||||
mInsetForeground.setCallback(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDetachedFromWindow() {
|
|
||||||
super.onDetachedFromWindow();
|
|
||||||
if (mInsetForeground != null) {
|
|
||||||
mInsetForeground.setCallback(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the calling container to specify a callback for custom processing when insets change (i.e. when
|
|
||||||
* {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
|
|
||||||
* UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
|
|
||||||
* clipToPadding to false.
|
|
||||||
*/
|
|
||||||
public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
|
|
||||||
mOnInsetsCallback = onInsetsCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface OnInsetsCallback {
|
|
||||||
public void onInsetsChanged(Rect insets);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.kabouzeid.gramophone.views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class SquareIfPlaceImageView extends ImageView {
|
||||||
|
private boolean forceSquare = false;
|
||||||
|
|
||||||
|
public SquareIfPlaceImageView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SquareIfPlaceImageView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SquareIfPlaceImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
final int small = Math.min(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
final int large = Math.max(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
|
||||||
|
if (forceSquare) super.onMeasure(small, small);
|
||||||
|
else if (View.MeasureSpec.getSize(large) > View.MeasureSpec.getSize(small) * 1.5)
|
||||||
|
super.onMeasure(small, small);
|
||||||
|
else super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forceSquare(boolean force) {
|
||||||
|
if (forceSquare != force) {
|
||||||
|
forceSquare = force;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,17 +7,17 @@ import android.widget.ImageView;
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class SquareImageView extends ImageView {
|
public class WidthFitSquareImageView extends ImageView {
|
||||||
|
|
||||||
public SquareImageView(Context context) {
|
public WidthFitSquareImageView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SquareImageView(Context context, AttributeSet attrs) {
|
public WidthFitSquareImageView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
|
public WidthFitSquareImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 645 B |
BIN
app/src/main/res/drawable-hdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 189 B |
BIN
app/src/main/res/drawable-hdpi/ic_playlist_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 131 B |
BIN
app/src/main/res/drawable-hdpi/ic_queue_white_24dp.png
Normal file
|
After Width: | Height: | Size: 227 B |
|
Before Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 614 B |
|
After Width: | Height: | Size: 439 B |
BIN
app/src/main/res/drawable-mdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 129 B |
BIN
app/src/main/res/drawable-mdpi/ic_playlist_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 114 B |
BIN
app/src/main/res/drawable-mdpi/ic_queue_white_24dp.png
Normal file
|
After Width: | Height: | Size: 164 B |
|
Before Width: | Height: | Size: 317 B |
|
Before Width: | Height: | Size: 418 B |
|
After Width: | Height: | Size: 785 B |
BIN
app/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 192 B |
BIN
app/src/main/res/drawable-xhdpi/ic_playlist_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 148 B |
BIN
app/src/main/res/drawable-xhdpi/ic_queue_white_24dp.png
Normal file
|
After Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 737 B |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 277 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_playlist_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_queue_white_24dp.png
Normal file
|
After Width: | Height: | Size: 349 B |
|
Before Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 1 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_check_white_96dp.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_playlist_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 246 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_queue_white_24dp.png
Normal file
|
After Width: | Height: | Size: 444 B |
|
Before Width: | Height: | Size: 746 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
|
@ -1,8 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
<size
|
<size
|
||||||
android:height="12dp"
|
android:height="20dp"
|
||||||
android:width="12dp"/>
|
android:width="3dp" />
|
||||||
<solid
|
<solid
|
||||||
android:color="@color/materialmusic_accent_color"/>
|
android:color="@color/black" />
|
||||||
</shape>
|
</shape>
|
||||||
|
|
@ -1,227 +0,0 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity$PlaceholderFragment">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/album_art"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/default_album_art"
|
|
||||||
android:transitionName="@string/transition_album_cover"
|
|
||||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/artist_image"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_above="@+id/footer"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_above="@+id/footer"
|
|
||||||
android:background="@drawable/shadow_up" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_above="@+id/footer"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
tools:ignore="RtlHardcoded">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/song_current_progress"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:fontFamily="sans-serif-medium"
|
|
||||||
android:gravity="bottom|left|start"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="16sp"
|
|
||||||
tools:ignore="RtlHardcoded" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/song_total_time"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:gravity="bottom|right|end"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="16sp"
|
|
||||||
tools:ignore="RtlHardcoded" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/footer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:background="?default_bar_color"
|
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:ignore="UnusedAttribute">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:transitionName="@string/transition_album_text"
|
|
||||||
tools:ignore="UnusedAttribute">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/song_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="sans-serif-medium"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
|
||||||
android:textColor="?attr/title_text_color" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/song_artist"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
|
||||||
android:textColor="?attr/caption_text_color" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/media_controller_placeholder"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="88dp"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:background="?attr/music_controller_container_color"
|
|
||||||
android:elevation="1dp"
|
|
||||||
tools:ignore="UnusedAttribute">
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/media_controller_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="88dp"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:background="?attr/music_controller_container_color"
|
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
tools:ignore="ContentDescription,UnusedAttribute">
|
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
style="@style/PlayPauseFab"
|
|
||||||
android:layout_centerInParent="true" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/prev_button"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginEnd="-4dp"
|
|
||||||
android:layout_marginRight="-4dp"
|
|
||||||
android:layout_toLeftOf="@+id/fab"
|
|
||||||
android:layout_toStartOf="@+id/fab"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:padding="14dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_skip_previous_white_48dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/next_button"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginLeft="-4dp"
|
|
||||||
android:layout_marginStart="-4dp"
|
|
||||||
android:layout_toEndOf="@+id/fab"
|
|
||||||
android:layout_toRightOf="@+id/fab"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:padding="14dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_skip_next_white_48dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/repeat_button"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:padding="14dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_repeat_grey600_48dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/shuffle_button"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:padding="14dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_shuffle_grey600_48dp" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/progress_slider"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_above="@+id/footer"
|
|
||||||
android:elevation="2dp"
|
|
||||||
android:padding="0dp"
|
|
||||||
android:progressTint="@color/materialmusic_accent_color"
|
|
||||||
android:thumbTint="@color/materialmusic_accent_color_darker"
|
|
||||||
tools:ignore="UnusedAttribute" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
style="@style/Toolbar"
|
|
||||||
android:layout_marginTop="@dimen/statusMargin"
|
|
||||||
android:background="@android:color/transparent" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
|
|
@ -3,14 +3,27 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ImageView
|
<FrameLayout
|
||||||
android:id="@+id/album_art"
|
android:background="?android:colorBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/header_image_height"
|
android:layout_height="@dimen/header_image_height">
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/default_album_art"
|
<ImageView
|
||||||
android:transitionName="@string/transition_album_cover"
|
android:id="@+id/album_art_background"
|
||||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<com.kabouzeid.gramophone.views.SquareIfPlaceImageView
|
||||||
|
android:id="@+id/album_art"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/default_album_art"
|
||||||
|
android:transitionName="@string/transition_album_cover"
|
||||||
|
tools:ignore="ContentDescription,UnusedAttribute" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/list_background"
|
android:id="@+id/list_background"
|
||||||
|
|
@ -61,25 +74,30 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<View
|
<include layout="@layout/status_bar" />
|
||||||
android:id="@+id/statusBar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/statusMargin"
|
|
||||||
android:background="@android:color/transparent" />
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<FrameLayout
|
||||||
android:id="@+id/toolbar"
|
android:layout_width="match_parent"
|
||||||
style="@style/Toolbar"
|
android:layout_height="wrap_content">
|
||||||
android:background="@android:color/transparent" />
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
style="@style/Toolbar"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
|
||||||
|
<ViewStub
|
||||||
|
android:id="@+id/cab_stub"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
android:layout_gravity="right|end"
|
android:layout_gravity="end|right|bottom"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_margin="16dp" />
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
tools:ignore="RtlHardcoded" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.kabouzeid.gramophone.views.SquareImageView
|
<com.kabouzeid.gramophone.views.WidthFitSquareImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
@ -159,7 +159,7 @@
|
||||||
android:gravity="start|left"
|
android:gravity="start|left"
|
||||||
tools:ignore="RtlHardcoded" />
|
tools:ignore="RtlHardcoded" />
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
android:layout_gravity="bottom|right|end"
|
android:layout_gravity="bottom|right|end"
|
||||||
|
|
|
||||||