New UI
This commit is contained in:
parent
fbd5e8bb61
commit
3f3818efb7
270 changed files with 7441 additions and 6502 deletions
|
@ -38,4 +38,5 @@ public class Constants {
|
|||
public static final String APP_TELEGRAM_LINK = "https://t.me/retromusicapp/";
|
||||
public static final String APP_TWITTER_LINK = "https://twitter.com/retromusicapp";
|
||||
public static final String FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md";
|
||||
public static final int CAST_SERVER_PORT = 8080;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package code.name.monkey.retromusic;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
|
||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
||||
import com.anjlab.android.iab.v3.TransactionDetails;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager;
|
||||
import code.name.monkey.retromusic.ui.activities.ErrorHandlerActivity;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
|
||||
|
||||
public class RetroApplication extends MultiDexApplication {
|
||||
|
@ -104,6 +103,12 @@ public class RetroApplication extends MultiDexApplication {
|
|||
//startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
Glide.with(this).onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
super.onTerminate();
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaMetadata;
|
||||
import com.google.android.gms.cast.framework.CastSession;
|
||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import code.name.monkey.retromusic.Constants;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
/**
|
||||
* Created by naman on 2/12/17.
|
||||
*/
|
||||
|
||||
public class CastHelper {
|
||||
|
||||
public static void startCasting(CastSession castSession, Song song) {
|
||||
|
||||
String ipAddress = RetroUtil.getIPAddress(true);
|
||||
URL baseUrl;
|
||||
try {
|
||||
baseUrl = new URL("http", ipAddress, Constants.CAST_SERVER_PORT, "");
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
String songUrl = baseUrl.toString() + "/song?id=" + song.id;
|
||||
String albumArtUrl = baseUrl.toString() + "/albumart?id=" + song.albumId;
|
||||
|
||||
MediaMetadata musicMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
|
||||
|
||||
musicMetadata.putString(MediaMetadata.KEY_TITLE, song.title);
|
||||
musicMetadata.putString(MediaMetadata.KEY_ARTIST, song.artistName);
|
||||
musicMetadata.putString(MediaMetadata.KEY_ALBUM_TITLE, song.albumName);
|
||||
musicMetadata.putInt(MediaMetadata.KEY_TRACK_NUMBER, song.trackNumber);
|
||||
musicMetadata.addImage(new WebImage(Uri.parse(albumArtUrl)));
|
||||
|
||||
try {
|
||||
MediaInfo mediaInfo = new MediaInfo.Builder(songUrl)
|
||||
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
||||
.setContentType("audio/mpeg")
|
||||
.setMetadata(musicMetadata)
|
||||
.setStreamDuration(song.duration)
|
||||
.build();
|
||||
RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
|
||||
remoteMediaClient.load(mediaInfo, true, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastOptions;
|
||||
import com.google.android.gms.cast.framework.OptionsProvider;
|
||||
import com.google.android.gms.cast.framework.SessionProvider;
|
||||
import com.google.android.gms.cast.framework.media.CastMediaOptions;
|
||||
import com.google.android.gms.cast.framework.media.MediaIntentReceiver;
|
||||
import com.google.android.gms.cast.framework.media.NotificationOptions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
public class CastOptionsProvider implements OptionsProvider {
|
||||
@Override
|
||||
public CastOptions getCastOptions(Context context) {
|
||||
List<String> buttonActions = new ArrayList<>();
|
||||
buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK);
|
||||
buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING);
|
||||
int[] compatButtonActionsIndicies = new int[]{ 0, 1 };
|
||||
|
||||
NotificationOptions notificationOptions = new NotificationOptions.Builder()
|
||||
.setActions(buttonActions, compatButtonActionsIndicies)
|
||||
.setTargetActivityClassName(ExpandedControlsActivity.class.getName())
|
||||
.build();
|
||||
|
||||
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
|
||||
.setNotificationOptions(notificationOptions)
|
||||
.setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName())
|
||||
.build();
|
||||
|
||||
return new CastOptions.Builder()
|
||||
.setReceiverApplicationId(context.getString(R.string.cast_app_id))
|
||||
.setCastMediaOptions(mediaOptions)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public class ExpandedControlsActivity extends ExpandedControllerActivity {
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.menu_expanded_controller, menu);
|
||||
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package code.name.monkey.retromusic.cast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import code.name.monkey.retromusic.Constants;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
|
||||
public class WebServer extends NanoHTTPD {
|
||||
|
||||
private Context context;
|
||||
private Uri songUri, albumArtUri;
|
||||
|
||||
public WebServer(Context context) {
|
||||
super(Constants.CAST_SERVER_PORT);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response serve(String uri, Method method,
|
||||
Map<String, String> header,
|
||||
Map<String, String> parameters,
|
||||
Map<String, String> files) {
|
||||
if (uri.contains("albumart")) {
|
||||
//serve the picture
|
||||
|
||||
String albumId = parameters.get("id");
|
||||
this.albumArtUri = RetroUtil.getAlbumArtUri(Long.parseLong(albumId));
|
||||
|
||||
if (albumArtUri != null) {
|
||||
String mediasend = "image/jpg";
|
||||
InputStream fisAlbumArt = null;
|
||||
try {
|
||||
fisAlbumArt = context.getContentResolver().openInputStream(albumArtUri);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Response.Status st = Response.Status.OK;
|
||||
|
||||
//serve the song
|
||||
return newChunkedResponse(st, mediasend, fisAlbumArt);
|
||||
}
|
||||
|
||||
} else if (uri.contains("song")) {
|
||||
|
||||
String songId = parameters.get("id");
|
||||
this.songUri = RetroUtil.getSongUri(context, Long.parseLong(songId));
|
||||
|
||||
if (songUri != null) {
|
||||
String mediasend = "audio/mp3";
|
||||
FileInputStream fisSong = null;
|
||||
File song = new File(songUri.getPath());
|
||||
try {
|
||||
fisSong = new FileInputStream(song);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Response.Status st = Response.Status.OK;
|
||||
|
||||
//serve the song
|
||||
return newFixedLengthResponse(st, mediasend, fisSong, song.length());
|
||||
}
|
||||
|
||||
}
|
||||
return newFixedLengthResponse("Error");
|
||||
}
|
||||
|
||||
}
|
|
@ -21,11 +21,12 @@ import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
|
|||
import java.util.ArrayList;
|
||||
|
||||
public class DeleteSongsDialog extends RoundedBottomSheetDialogFragment {
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.action_delete)
|
||||
TextView delete;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.action_cancel)
|
||||
TextView cancel;
|
||||
|
||||
|
@ -63,28 +64,26 @@ public class DeleteSongsDialog extends RoundedBottomSheetDialogFragment {
|
|||
dismiss();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
delete.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
delete.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
cancel.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
|
||||
|
||||
//noinspection unchecked,ConstantConditions
|
||||
final ArrayList<Song> songs = getArguments().getParcelableArrayList("songs");
|
||||
int title;
|
||||
CharSequence content;
|
||||
if (songs != null) {
|
||||
if (songs.size() > 1) {
|
||||
title = R.string.delete_songs_title;
|
||||
content = Html.fromHtml(getString(R.string.delete_x_songs, songs.size()));
|
||||
} else {
|
||||
title = R.string.delete_song_title;
|
||||
content = Html.fromHtml(getString(R.string.delete_song_x, songs.get(0).title));
|
||||
}
|
||||
this.title.setText(title);
|
||||
this.delete.setText(content);
|
||||
this.title.setText(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.widget.TextView;
|
|||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.BindViews;
|
||||
|
@ -22,12 +21,8 @@ import butterknife.ButterKnife;
|
|||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView;
|
||||
import code.name.monkey.appthemehelper.common.views.ATESecondaryTextView;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment;
|
||||
import code.name.monkey.retromusic.util.Compressor;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
@ -45,20 +40,15 @@ import static code.name.monkey.retromusic.Constants.USER_PROFILE;
|
|||
public class HomeOptionDialog extends RoundedBottomSheetDialogFragment {
|
||||
|
||||
private static final String TAG = "HomeOptionDialog";
|
||||
static ButterKnife.Setter<TextView, Integer> textColor = (view, value, index) -> view.setTextColor(value.intValue());
|
||||
Unbinder mUnbinder;
|
||||
|
||||
@BindView(R.id.user_image_bottom)
|
||||
CircularImageView userImageBottom;
|
||||
|
||||
@BindView(R.id.title_welcome)
|
||||
AppCompatTextView titleWelcome;
|
||||
|
||||
@BindViews({R.id.tv_about, R.id.title_welcome, R.id.text, R.id.tv_buy_pro, R.id.tv_folder, R.id.tv_rate_app,
|
||||
@BindViews({R.id.tv_about, R.id.title_welcome, R.id.text, R.id.tv_buy_pro, R.id.tv_rate_app,
|
||||
R.id.tv_settings, R.id.tv_sleep_timer})
|
||||
List<TextView> textViews;
|
||||
|
||||
static ButterKnife.Setter<TextView, Integer> textColor = (view, value, index) -> view.setTextColor(value.intValue());
|
||||
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
@Nullable
|
||||
|
@ -67,8 +57,7 @@ public class HomeOptionDialog extends RoundedBottomSheetDialogFragment {
|
|||
@Nullable Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.user_action_details, container, false);
|
||||
mUnbinder = ButterKnife.bind(this, layout);
|
||||
layout.findViewById(R.id.action_buy_pro).setVisibility(RetroApplication.isProVersion() ? View
|
||||
.GONE : View.VISIBLE);
|
||||
layout.findViewById(R.id.action_buy_pro).setVisibility(RetroApplication.isProVersion() ? View.GONE : View.VISIBLE);
|
||||
ButterKnife.apply(textViews, textColor, ThemeStore.textColorPrimary(getContext()));
|
||||
return layout;
|
||||
}
|
||||
|
@ -110,7 +99,7 @@ public class HomeOptionDialog extends RoundedBottomSheetDialogFragment {
|
|||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@OnClick({R.id.action_about, R.id.user_info_container, R.id.action_buy_pro, R.id.action_folder,
|
||||
@OnClick({R.id.action_about, R.id.user_info_container, R.id.action_buy_pro,
|
||||
R.id.action_settings, R.id.action_sleep_timer, R.id.action_rate})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
|
@ -120,14 +109,7 @@ public class HomeOptionDialog extends RoundedBottomSheetDialogFragment {
|
|||
case R.id.action_rate:
|
||||
NavigationUtil.goToPlayStore(getActivity());
|
||||
break;
|
||||
case R.id.action_folder:
|
||||
MainActivity mainActivity = (MainActivity) getActivity();
|
||||
if (mainActivity == null) {
|
||||
return;
|
||||
}
|
||||
mainActivity.setCurrentFragment(FoldersFragment.newInstance(getContext()), true,
|
||||
FoldersFragment.TAG);
|
||||
break;
|
||||
|
||||
case R.id.action_settings:
|
||||
NavigationUtil.goToSettings(getActivity());
|
||||
break;
|
||||
|
|
|
@ -16,7 +16,6 @@ import android.support.annotation.Nullable;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
@ -44,6 +43,8 @@ public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
|||
TextView setButton;
|
||||
@BindView(R.id.action_cancel)
|
||||
TextView cancelButton;
|
||||
@BindView(R.id.action_cancel_container)
|
||||
View cancelButtonContainer;
|
||||
|
||||
private int seekArcProgress;
|
||||
private TimerUpdater timerUpdater;
|
||||
|
@ -76,6 +77,7 @@ public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
|||
clipDrawable.setColorFilter(dark, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
@ -84,8 +86,6 @@ public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
|||
seekArcProgress = PreferenceUtil.getInstance(getActivity()).getLastSleepTimerValue();
|
||||
updateTimeDisplayTime();
|
||||
seekArc.setProgress(seekArcProgress);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
setProgressBarColor(ThemeStore.accentColor(getContext()));
|
||||
|
||||
seekArc.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
|
@ -161,6 +161,7 @@ public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
|||
|
||||
private class TimerUpdater extends CountDownTimer {
|
||||
TimerUpdater() {
|
||||
//noinspection ConstantConditions
|
||||
super(PreferenceUtil.getInstance(getActivity()).getNextSleepTimerElapsedRealTime() - SystemClock.elapsedRealtime(), 1000);
|
||||
}
|
||||
|
||||
|
@ -173,6 +174,7 @@ public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
|||
@Override
|
||||
public void onFinish() {
|
||||
cancelButton.setText(null);
|
||||
cancelButtonContainer.setVisibility(View.GONE);
|
||||
//materialDialog.setActionButton(DialogAction.NEUTRAL, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,12 +34,11 @@ import io.reactivex.schedulers.Schedulers;
|
|||
|
||||
|
||||
public class MusicPlayerRemote {
|
||||
|
||||
public static final String TAG = MusicPlayerRemote.class.getSimpleName();
|
||||
private static final WeakHashMap<Context, ServiceBinder> mConnectionMap = new WeakHashMap<>();
|
||||
@Nullable
|
||||
public static MusicService musicService;
|
||||
|
||||
|
||||
public static ServiceToken bindToService(@NonNull final Context context,
|
||||
final ServiceConnection callback) {
|
||||
Activity realActivity = ((Activity) context).getParent();
|
||||
|
@ -444,6 +443,10 @@ public class MusicPlayerRemote {
|
|||
return musicService != null;
|
||||
}
|
||||
|
||||
@interface PlaybackLocation {
|
||||
int REMOTE = 0;
|
||||
int LOCAL = 1;
|
||||
}
|
||||
|
||||
public static final class ServiceBinder implements ServiceConnection {
|
||||
private final ServiceConnection mCallback;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package code.name.monkey.retromusic.misc;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.MediaRouteActionProvider;
|
||||
import android.support.v7.app.MediaRouteButton;
|
||||
import android.support.v7.media.MediaRouteSelector;
|
||||
import android.util.Log;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.views.CustomMediaRouteButton;
|
||||
|
||||
public class CustomMediaRouteActionProvider extends MediaRouteActionProvider {
|
||||
private static final String TAG = "MediaRteActProvider";
|
||||
|
||||
private Activity activity;
|
||||
|
||||
private MediaRouteSelector selector = MediaRouteSelector.EMPTY;
|
||||
private CustomMediaRouteButton customMediaRouteButton;
|
||||
|
||||
public CustomMediaRouteActionProvider(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void setActivity(@NonNull Activity activity) {
|
||||
this.activity = activity;
|
||||
if (customMediaRouteButton != null) {
|
||||
customMediaRouteButton.setActivity(activity);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaRouteButton getMediaRouteButton() {
|
||||
return customMediaRouteButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the media route button is being created.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public CustomMediaRouteButton onCreateMediaRouteButton() {
|
||||
if (customMediaRouteButton != null) {
|
||||
Log.e(TAG, "onCreateMediaRouteButton: This ActionProvider is already associated "
|
||||
+ "with a menu item. Don't reuse MediaRouteActionProvider instances! "
|
||||
+ "Abandoning the old button...");
|
||||
}
|
||||
|
||||
customMediaRouteButton = new CustomMediaRouteButton(getContext());
|
||||
customMediaRouteButton.setActivity(activity);
|
||||
customMediaRouteButton.setAlpha(RetroApplication.isProVersion() ? 1.0f : 0.5f);
|
||||
customMediaRouteButton.setRouteSelector(selector);
|
||||
customMediaRouteButton.setLayoutParams(new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT));
|
||||
return customMediaRouteButton;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package code.name.monkey.retromusic.misc;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import butterknife.BindInt;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
/**
|
||||
* {@link View.OnClickListener} used to translate the product grid sheet downward on
|
||||
* the Y-axis when the navigation icon in the toolbar is pressed.
|
||||
*/
|
||||
public class NavigationIconClickListener implements View.OnClickListener {
|
||||
|
||||
private final AnimatorSet animatorSet = new AnimatorSet();
|
||||
@BindInt(R.integer.options_height)
|
||||
int options;
|
||||
private Context context;
|
||||
private View sheet, menu;
|
||||
private Interpolator interpolator;
|
||||
private int height;
|
||||
private boolean backdropShown = false;
|
||||
private Drawable openIcon;
|
||||
private Drawable closeIcon;
|
||||
|
||||
public NavigationIconClickListener(Context context, View sheet, View menu, @Nullable Interpolator interpolator) {
|
||||
this(context, sheet, menu, interpolator, null, null);
|
||||
}
|
||||
|
||||
public NavigationIconClickListener(Context context, View sheet, View menu, @Nullable Interpolator interpolator,
|
||||
@Nullable Drawable openIcon, @Nullable Drawable closeIcon) {
|
||||
this.context = context;
|
||||
this.sheet = sheet;
|
||||
this.menu = menu;
|
||||
this.interpolator = interpolator;
|
||||
this.openIcon = openIcon;
|
||||
this.closeIcon = closeIcon;
|
||||
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
height = displayMetrics.heightPixels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
backdropShown = !backdropShown;
|
||||
|
||||
// Cancel the existing animations
|
||||
animatorSet.removeAllListeners();
|
||||
animatorSet.end();
|
||||
animatorSet.cancel();
|
||||
|
||||
if (!(view instanceof ImageView)) {
|
||||
throw new IllegalArgumentException("updateIcon() must be called on an ImageView");
|
||||
}
|
||||
updateIcon((ImageView) view);
|
||||
final int translateY = (int) RetroUtil.convertDpToPixel(RetroUtil.isLandscape(view.getResources()) ? 3 * 48 : 5 * 48, view.getContext());
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(sheet, "translationY", backdropShown ? translateY : 0);
|
||||
animator.setDuration(500);
|
||||
if (interpolator != null) {
|
||||
animator.setInterpolator(interpolator);
|
||||
}
|
||||
animatorSet.play(animator);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
private void updateIcon(ImageView view) {
|
||||
if (openIcon != null && closeIcon != null) {
|
||||
view.setImageTintList(ColorStateList.valueOf(ATHUtil.resolveColor(context, R.attr.iconColor)));
|
||||
if (backdropShown) {
|
||||
view.setImageDrawable(closeIcon);
|
||||
} else {
|
||||
view.setImageDrawable(openIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,30 +70,42 @@ public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
private static final int TAG_EDITOR_REQUEST = 2001;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
|
||||
@BindView(R.id.song_title)
|
||||
AppCompatTextView songTitle;
|
||||
|
||||
@BindView(R.id.action_shuffle_all)
|
||||
FloatingActionButton shuffleButton;
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
@Nullable
|
||||
CollapsingToolbarLayout collapsingToolbarLayout;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
@Nullable
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
@BindView(R.id.content)
|
||||
View contentContainer;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.more_recycler_view)
|
||||
RecyclerView moreRecyclerView;
|
||||
|
||||
@BindView(R.id.more_title)
|
||||
TextView moreTitle;
|
||||
|
||||
@BindView(R.id.artist_image)
|
||||
ImageView artistImage;
|
||||
|
||||
|
@ -114,7 +126,7 @@ public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
|
||||
supportPostponeEnterTransition();
|
||||
setupToolbarMarginHeight();
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
setLightNavigationBar(true);
|
||||
setNavigationbarColorAuto();
|
||||
|
||||
|
@ -132,9 +144,9 @@ public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
}
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(null);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
if (toolbar != null && !PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar
|
||||
|
@ -177,7 +189,9 @@ public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
artistPairs);
|
||||
break;
|
||||
case R.id.action_shuffle_all:
|
||||
MusicPlayerRemote.openAndShuffleQueue(album.songs, true);
|
||||
if (album.songs != null) {
|
||||
MusicPlayerRemote.openAndShuffleQueue(album.songs, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +329,7 @@ public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
|
||||
MenuItem sortOrder = menu.findItem(R.id.action_sort_order);
|
||||
setUpSortOrderMenu(sortOrder.getSubMenu());
|
||||
return true;
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,40 +72,55 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
@BindView(R.id.app_bar)
|
||||
@Nullable
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
@Nullable
|
||||
CollapsingToolbarLayout collapsingToolbarLayout;
|
||||
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
|
||||
@BindView(R.id.biography)
|
||||
TextView biographyTextView;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.album_recycler_view)
|
||||
RecyclerView albumRecyclerView;
|
||||
|
||||
@BindView(R.id.album_title)
|
||||
AppCompatTextView albumTitle;
|
||||
|
||||
@BindView(R.id.song_title)
|
||||
AppCompatTextView songTitle;
|
||||
|
||||
@BindView(R.id.biography_title)
|
||||
AppCompatTextView biographyTitle;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
|
||||
@BindView(R.id.action_shuffle_all)
|
||||
FloatingActionButton shuffleButton;
|
||||
|
||||
@BindView(R.id.gradient_background)
|
||||
@Nullable
|
||||
View background;
|
||||
|
||||
@BindView(R.id.image_container)
|
||||
@Nullable
|
||||
View imageContainer;
|
||||
|
||||
@BindView(R.id.content)
|
||||
View contentContainer;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@Nullable
|
||||
private Spanned biography;
|
||||
private Artist artist;
|
||||
|
@ -125,7 +140,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
|||
setDrawUnderStatusBar(true);
|
||||
super.onCreate(bundle);
|
||||
ButterKnife.bind(this);
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
setNavigationbarColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import butterknife.OnClick;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
public class ErrorHandlerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error_handler);
}
@OnClick(R.id.clear_app_data)
void clearAppDate(View view) {
RetroApplication.deleteAppData();
}
}
|
||||
package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import butterknife.OnClick;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
public class ErrorHandlerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error_handler);
}
@OnClick(R.id.clear_app_data)
void clearAppDate(View view) {
RetroApplication.deleteAppData();
}
}
|
|
@ -96,8 +96,6 @@ public class GenreDetailsActivity extends AbsSlidingMusicPanelActivity implement
|
|||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
RetroUtil.statusBarHeight(statusBar);
|
||||
|
||||
genre = getIntent().getParcelableExtra(EXTRA_GENRE_ID);
|
||||
|
|
|
@ -15,6 +15,18 @@ import android.view.WindowManager;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
@ -33,307 +45,304 @@ import code.name.monkey.retromusic.util.MusicUtil;
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.LyricView;
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.bumptech.glide.Glide;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
public class LyricsActivity extends AbsMusicServiceActivity implements
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView songTitle;
|
||||
@BindView(R.id.text)
|
||||
TextView songText;
|
||||
@BindView(R.id.lyrics_view)
|
||||
LyricView lyricView;
|
||||
@BindView(R.id.offline_lyrics)
|
||||
TextView offlineLyrics;
|
||||
@BindView(R.id.actions)
|
||||
RadioGroup actionsLayout;
|
||||
@BindView(R.id.gradient_background)
|
||||
View background;
|
||||
@BindView(R.id.title)
|
||||
TextView songTitle;
|
||||
|
||||
private MusicProgressViewUpdateHelper updateHelper;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
private CompositeDisposable disposable;
|
||||
private Song song;
|
||||
private Lyrics lyrics;
|
||||
@BindView(R.id.text)
|
||||
TextView songText;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_lyrics);
|
||||
ButterKnife.bind(this);
|
||||
@BindView(R.id.lyrics_view)
|
||||
LyricView lyricView;
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
@BindView(R.id.offline_lyrics)
|
||||
TextView offlineLyrics;
|
||||
|
||||
updateHelper = new MusicProgressViewUpdateHelper(this, 500, 1000);
|
||||
@BindView(R.id.actions)
|
||||
RadioGroup actionsLayout;
|
||||
|
||||
setupLyricsView();
|
||||
setupWakelock();
|
||||
@BindView(R.id.gradient_background)
|
||||
View background;
|
||||
|
||||
actionsLayout.setOnCheckedChangeListener((group, checkedId) -> selectLyricsTye(checkedId));
|
||||
private MusicProgressViewUpdateHelper updateHelper;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
private CompositeDisposable disposable;
|
||||
private Song song;
|
||||
private Lyrics lyrics;
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_lyrics);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
private void selectLyricsTye(int group) {
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
RadioButton radioButton = actionsLayout.findViewById(group);
|
||||
radioButton.setBackgroundTintList(ColorStateList.valueOf(ThemeStore.accentColor(this)));
|
||||
radioButton.setTextColor(ThemeStore.textColorPrimary(this));
|
||||
updateHelper = new MusicProgressViewUpdateHelper(this, 500, 1000);
|
||||
|
||||
offlineLyrics.setVisibility(View.GONE);
|
||||
lyricView.setVisibility(View.GONE);
|
||||
setupLyricsView();
|
||||
setupWakelock();
|
||||
loadLrcFile();
|
||||
|
||||
switch (group) {
|
||||
case R.id.synced_lyrics:
|
||||
loadLRCLyrics();
|
||||
lyricView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
default:
|
||||
case R.id.normal_lyrics:
|
||||
loadSongLyrics();
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
actionsLayout.setOnCheckedChangeListener((group, checkedId) -> selectLyricsTye(checkedId));
|
||||
actionsLayout.check(PreferenceUtil.getInstance(this).getLastLyricsType());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLRCLyrics() {
|
||||
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
||||
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName));
|
||||
private void selectLyricsTye(int group) {
|
||||
PreferenceUtil.getInstance(this).setLastLyricsType(group);
|
||||
RadioButton radioButton = actionsLayout.findViewById(group);
|
||||
radioButton.setBackgroundTintList(ColorStateList.valueOf(ThemeStore.accentColor(this)));
|
||||
radioButton.setTextColor(ThemeStore.textColorPrimary(this));
|
||||
|
||||
offlineLyrics.setVisibility(View.GONE);
|
||||
lyricView.setVisibility(View.GONE);
|
||||
|
||||
switch (group) {
|
||||
case R.id.synced_lyrics:
|
||||
loadLRCLyrics();
|
||||
lyricView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
default:
|
||||
case R.id.normal_lyrics:
|
||||
loadSongLyrics();
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupWakelock() {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
|
||||
private void setupLyricsView() {
|
||||
disposable = new CompositeDisposable();
|
||||
|
||||
lyricView
|
||||
.setOnPlayerClickListener((progress, content) -> MusicPlayerRemote.seekTo((int) progress));
|
||||
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
|
||||
lyricView.setDefaultColor(ContextCompat.getColor(this, R.color.md_grey_400));
|
||||
//lyricView.setTouchable(false);
|
||||
lyricView.setHintColor(Color.WHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
updateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposable.clear();
|
||||
|
||||
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask.isCancelled()) {
|
||||
updateLyricsAsyncTask.cancel(true);
|
||||
private void loadLRCLyrics() {
|
||||
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
||||
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
private void setupWakelock() {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
lyricView.setCurrentTimeMillis(progress);
|
||||
}
|
||||
private void setupLyricsView() {
|
||||
disposable = new CompositeDisposable();
|
||||
|
||||
private void loadLrcFile() {
|
||||
song = MusicPlayerRemote.getCurrentSong();
|
||||
songTitle.setText(song.title);
|
||||
songText.setText(song.artistName);
|
||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
||||
.checkIgnoreMediaStore(this)
|
||||
.generatePalette(this)
|
||||
.build()
|
||||
.into(new RetroMusicColoredTarget(findViewById(R.id.image)) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (PreferenceUtil.getInstance(LyricsActivity.this).getAdaptiveColor()) {
|
||||
background.setBackgroundColor(color);
|
||||
lyricView
|
||||
.setOnPlayerClickListener((progress, content) -> MusicPlayerRemote.seekTo((int) progress));
|
||||
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
|
||||
lyricView.setDefaultColor(ContextCompat.getColor(this, R.color.md_grey_400));
|
||||
//lyricView.setTouchable(false);
|
||||
lyricView.setHintColor(Color.WHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
updateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposable.clear();
|
||||
|
||||
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask.isCancelled()) {
|
||||
updateLyricsAsyncTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
lyricView.setCurrentTimeMillis(progress);
|
||||
}
|
||||
|
||||
private void loadLrcFile() {
|
||||
song = MusicPlayerRemote.getCurrentSong();
|
||||
songTitle.setText(song.title);
|
||||
songText.setText(song.artistName);
|
||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
||||
.checkIgnoreMediaStore(this)
|
||||
.generatePalette(this)
|
||||
.build()
|
||||
.into(new RetroMusicColoredTarget(findViewById(R.id.image)) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (PreferenceUtil.getInstance(LyricsActivity.this).getAdaptiveColor()) {
|
||||
background.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showLyricsLocal(File file) {
|
||||
if (file == null) {
|
||||
lyricView.reset();
|
||||
} else {
|
||||
lyricView.setLyricFile(file, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick({R.id.edit_lyrics, R.id.back})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.back:
|
||||
onBackPressed();
|
||||
break;
|
||||
case R.id.edit_lyrics:
|
||||
switch (actionsLayout.getCheckedRadioButtonId()) {
|
||||
case R.id.synced_lyrics:
|
||||
showSyncedLyrics();
|
||||
break;
|
||||
case R.id.normal_lyrics:
|
||||
showLyricsSaveDialog();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void loadSongLyrics() {
|
||||
if (updateLyricsAsyncTask != null) {
|
||||
updateLyricsAsyncTask.cancel(false);
|
||||
}
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
updateLyricsAsyncTask = new AsyncTask<Void, Void, Lyrics>() {
|
||||
@Override
|
||||
protected Lyrics doInBackground(Void... params) {
|
||||
String data = MusicUtil.getLyrics(song);
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
return Lyrics.parse(song, data);
|
||||
}
|
||||
}
|
||||
});
|
||||
selectLyricsTye(actionsLayout.getCheckedRadioButtonId());
|
||||
}
|
||||
|
||||
private void showLyricsLocal(File file) {
|
||||
if (file == null) {
|
||||
lyricView.reset();
|
||||
} else {
|
||||
lyricView.setLyricFile(file, "UTF-8");
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyrics = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Lyrics l) {
|
||||
lyrics = l;
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
if (l == null) {
|
||||
offlineLyrics.setText(R.string.no_lyrics_found);
|
||||
return;
|
||||
}
|
||||
offlineLyrics.setText(l.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(Lyrics s) {
|
||||
onPostExecute(null);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick({R.id.edit_lyrics, R.id.back})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.back:
|
||||
onBackPressed();
|
||||
break;
|
||||
case R.id.edit_lyrics:
|
||||
switch (actionsLayout.getCheckedRadioButtonId()) {
|
||||
case R.id.synced_lyrics:
|
||||
showSyncedLyrics();
|
||||
break;
|
||||
case R.id.normal_lyrics:
|
||||
showLyricsSaveDialog();
|
||||
break;
|
||||
private void showSyncedLyrics() {
|
||||
String content = "";
|
||||
try {
|
||||
content = LyricUtil.getStringFromFile(song.title, song.artistName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.content("Add time frame lyrics")
|
||||
.negativeText("Delete")
|
||||
.onNegative((dialog, which) -> {
|
||||
LyricUtil.deleteLrcFile(song.title, song.artistName);
|
||||
loadLrcFile();
|
||||
})
|
||||
.onNeutral(
|
||||
(dialog, which) -> RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchLrcUrl()))
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
LyricUtil.writeLrcToLoc(song.title, song.artistName, input.toString());
|
||||
loadLrcFile();
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void loadSongLyrics() {
|
||||
if (updateLyricsAsyncTask != null) {
|
||||
updateLyricsAsyncTask.cancel(false);
|
||||
private String getGoogleSearchLrcUrl() {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = song.title + "+" + song.artistName;
|
||||
query = "q=" + query.replace(" ", "+") + " .lrc";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
updateLyricsAsyncTask = new AsyncTask<Void, Void, Lyrics>() {
|
||||
@Override
|
||||
protected Lyrics doInBackground(Void... params) {
|
||||
String data = MusicUtil.getLyrics(song);
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
return null;
|
||||
|
||||
private void showLyricsSaveDialog() {
|
||||
String content = "";
|
||||
if (lyrics == null) {
|
||||
content = "";
|
||||
} else {
|
||||
content = lyrics.data;
|
||||
}
|
||||
return Lyrics.parse(song, data);
|
||||
}
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.onNeutral(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchUrl(song.title, song.artistName));
|
||||
}
|
||||
})
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.LYRICS, input.toString());
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyrics = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Lyrics l) {
|
||||
lyrics = l;
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
if (l == null) {
|
||||
offlineLyrics.setText(R.string.no_lyrics_found);
|
||||
return;
|
||||
}
|
||||
offlineLyrics.setText(l.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(Lyrics s) {
|
||||
onPostExecute(null);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void showSyncedLyrics() {
|
||||
String content = "";
|
||||
try {
|
||||
content = LyricUtil.getStringFromFile(song.title, song.artistName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
new WriteTagsAsyncTask(LyricsActivity.this)
|
||||
.execute(
|
||||
new WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null));
|
||||
loadLrcFile();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.content("Add time frame lyrics")
|
||||
.negativeText("Delete")
|
||||
.onNegative((dialog, which) -> {
|
||||
LyricUtil.deleteLrcFile(song.title, song.artistName);
|
||||
loadLrcFile();
|
||||
})
|
||||
.onNeutral(
|
||||
(dialog, which) -> RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchLrcUrl()))
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
LyricUtil.writeLrcToLoc(song.title, song.artistName, input.toString());
|
||||
loadLrcFile();
|
||||
}).show();
|
||||
}
|
||||
|
||||
private String getGoogleSearchLrcUrl() {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = song.title + "+" + song.artistName;
|
||||
query = "q=" + query.replace(" ", "+") + " .lrc";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
private void showLyricsSaveDialog() {
|
||||
String content = "";
|
||||
if (lyrics == null) {
|
||||
content = "";
|
||||
} else {
|
||||
content = lyrics.data;
|
||||
private ArrayList<String> getSongPaths(Song song) {
|
||||
ArrayList<String> paths = new ArrayList<>(1);
|
||||
paths.add(song.data);
|
||||
return paths;
|
||||
}
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.onNeutral(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchUrl(song.title, song.artistName));
|
||||
}
|
||||
})
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.LYRICS, input.toString());
|
||||
|
||||
new WriteTagsAsyncTask(LyricsActivity.this)
|
||||
.execute(
|
||||
new WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null));
|
||||
loadLrcFile();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private ArrayList<String> getSongPaths(Song song) {
|
||||
ArrayList<String> paths = new ArrayList<>(1);
|
||||
paths.add(song.data);
|
||||
return paths;
|
||||
}
|
||||
|
||||
private String getGoogleSearchUrl(String title, String text) {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = title + "+" + text;
|
||||
query = "q=" + query.replace(" ", "+") + " lyrics";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
private String getGoogleSearchUrl(String title, String text) {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = title + "+" + text;
|
||||
query = "q=" + query.replace(" ", "+") + " lyrics";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import code.name.monkey.retromusic.model.Song;
|
|||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.HomeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
@ -59,6 +60,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
|||
private static final int APP_USER_INFO_REQUEST = 9003;
|
||||
private static final int REQUEST_CODE_THEME = 9002;
|
||||
|
||||
public static final int LIBRARY = 1;
|
||||
public static final int FOLDERS = 3;
|
||||
public static final int HOME = 0;
|
||||
|
||||
@Nullable
|
||||
MainActivityFragmentCallbacks currentFragment;
|
||||
|
||||
|
@ -83,7 +88,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
@SuppressLint("InflateParams")
|
||||
|
@ -100,20 +104,21 @@ public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
|||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setBottomBarVisibility(View.VISIBLE);
|
||||
|
||||
drawerLayout.setOnApplyWindowInsetsListener((view, windowInsets) ->
|
||||
windowInsets.replaceSystemWindowInsets(0, 0, 0, 0));
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
setCurrentFragment(PreferenceUtil.getInstance(this).getLastPage());
|
||||
setCurrentFragment(PreferenceUtil.getInstance(this).getLastMusicChooser());
|
||||
} else {
|
||||
restoreCurrentFragment();
|
||||
}
|
||||
getBottomNavigationView().setOnNavigationItemSelectedListener(this);
|
||||
//getBottomNavigationView().setOnNavigationItemSelectedListener(this);
|
||||
checkShowChangelog();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void checkShowChangelog() {
|
||||
try {
|
||||
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
|
@ -182,19 +187,18 @@ public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
|||
return true;
|
||||
}
|
||||
|
||||
private void setCurrentFragment(int menuItem) {
|
||||
public void setCurrentFragment(int menuItem) {
|
||||
PreferenceUtil.getInstance(this).setLastMusicChooser(menuItem);
|
||||
switch (menuItem) {
|
||||
case R.id.action_song:
|
||||
case R.id.action_album:
|
||||
case R.id.action_artist:
|
||||
case R.id.action_playlist:
|
||||
setCurrentFragment(LibraryFragment.newInstance(menuItem), false, LibraryFragment.TAG);
|
||||
break;
|
||||
default:
|
||||
case R.id.action_home:
|
||||
setCurrentFragment(PreferenceUtil.getInstance(this).toggleHomeBanner() ?
|
||||
BannerHomeFragment.newInstance() : HomeFragment.newInstance(), false,
|
||||
HomeFragment.TAG);
|
||||
case LIBRARY:
|
||||
setCurrentFragment(LibraryFragment.newInstance(), false, LibraryFragment.TAG);
|
||||
break;
|
||||
case FOLDERS:
|
||||
setCurrentFragment(FoldersFragment.newInstance(this), false, FoldersFragment.TAG);
|
||||
break;
|
||||
case HOME:
|
||||
setCurrentFragment(PreferenceUtil.getInstance(this).toggleHomeBanner() ? HomeFragment.newInstance() : BannerHomeFragment.newInstance(), false, HomeFragment.TAG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +273,6 @@ public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
|||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
|
|
@ -94,7 +94,6 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
|
|||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
playlist = getIntent().getExtras().getParcelable(EXTRA_PLAYLIST);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.support.v7.widget.Toolbar;
|
|||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
||||
|
@ -43,12 +44,16 @@ public class ProVersionActivity extends AbsBaseActivity implements
|
|||
|
||||
@BindView(R.id.purchase_button)
|
||||
View purchaseButton;
|
||||
@BindView(R.id.app_bar)
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBar;
|
||||
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
private BillingProcessor billingProcessor;
|
||||
private AsyncTask restorePurchaseAsyncTask;
|
||||
|
||||
|
|
|
@ -6,16 +6,11 @@ import android.content.Intent;
|
|||
import android.os.Bundle;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.transition.TransitionManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.SearchView.OnQueryTextListener;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
@ -29,7 +24,6 @@ import java.util.Locale;
|
|||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.mvp.contract.SearchContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter;
|
||||
|
@ -51,24 +45,12 @@ public class SearchActivity extends AbsMusicServiceActivity implements OnQueryTe
|
|||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.search_view)
|
||||
EditText searchView;
|
||||
|
||||
@BindView(R.id.root)
|
||||
CoordinatorLayout container;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appbar;
|
||||
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
|
@ -155,26 +137,12 @@ public class SearchActivity extends AbsMusicServiceActivity implements OnQueryTe
|
|||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
title.setTextColor(ThemeStore.textColorPrimary(this));
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
setSupportActionBar(toolbar);
|
||||
setTitle(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void search(@NonNull String query) {
|
||||
this.query = query.trim();
|
||||
TransitionManager.beginDelayedTransition(toolbar);
|
||||
micIcon.setVisibility(query.length() > 0 ? View.GONE : View.VISIBLE);
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
|
@ -242,15 +210,21 @@ public class SearchActivity extends AbsMusicServiceActivity implements OnQueryTe
|
|||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.voice_search)
|
||||
void searchImageView() {
|
||||
startMicSearch();
|
||||
@OnClick({R.id.voice_search, R.id.back})
|
||||
void searchImageView(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.voice_search:
|
||||
startMicSearch();
|
||||
break;
|
||||
case R.id.back:
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void startMicSearch() {
|
||||
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
|
||||
intent
|
||||
.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
||||
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
||||
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
|
||||
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt));
|
||||
try {
|
||||
|
|
|
@ -32,10 +32,13 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.detail_content_frame)
|
||||
@Nullable
|
||||
FrameLayout detailsFrame;
|
||||
|
@ -89,12 +92,12 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia
|
|||
private void setupToolbar() {
|
||||
title.setTextColor(ThemeStore.textColorPrimary(this));
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
appBarLayout.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
appBarLayout.setBackgroundColor(primaryColor);
|
||||
setTitle(null);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.support.design.widget.Snackbar;
|
|||
import android.support.v4.app.ActivityCompat;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
|
||||
|
@ -22,136 +23,136 @@ import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
|
|||
|
||||
public abstract class AbsBaseActivity extends AbsThemeActivity {
|
||||
|
||||
public static final int PERMISSION_REQUEST = 100;
|
||||
private boolean hadPermissions;
|
||||
private String[] permissions;
|
||||
private String permissionDeniedMessage;
|
||||
public static final int PERMISSION_REQUEST = 100;
|
||||
private boolean hadPermissions;
|
||||
private String[] permissions;
|
||||
private String permissionDeniedMessage;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissions = getPermissionsToRequest();
|
||||
hadPermissions = hasPermissions();
|
||||
permissions = getPermissionsToRequest();
|
||||
hadPermissions = hasPermissions();
|
||||
|
||||
setPermissionDeniedMessage(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
if (!hasPermissions()) {
|
||||
requestPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
final boolean hasPermissions = hasPermissions();
|
||||
if (hasPermissions != hadPermissions) {
|
||||
hadPermissions = hasPermissions;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
onHasPermissionsChanged(hasPermissions);
|
||||
}
|
||||
setPermissionDeniedMessage(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void onHasPermissionsChanged(boolean hasPermissions) {
|
||||
// implemented by sub classes
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_UP) {
|
||||
showOverflowMenu();
|
||||
return true;
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
protected void showOverflowMenu() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String[] getPermissionsToRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected View getSnackBarContainer() {
|
||||
return getWindow().getDecorView();
|
||||
}
|
||||
|
||||
private String getPermissionDeniedMessage() {
|
||||
return permissionDeniedMessage == null ? getString(R.string.permissions_denied)
|
||||
: permissionDeniedMessage;
|
||||
}
|
||||
|
||||
protected void setPermissionDeniedMessage(String message) {
|
||||
permissionDeniedMessage = message;
|
||||
}
|
||||
|
||||
protected void requestPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
requestPermissions(permissions, PERMISSION_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
for (String permission : permissions) {
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
return false;
|
||||
@Override
|
||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
if (!hasPermissions()) {
|
||||
requestPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == PERMISSION_REQUEST) {
|
||||
for (int grantResult : grantResults) {
|
||||
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(AbsBaseActivity.this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
//User has deny from permission dialog
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_grant, view -> requestPermissions())
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
} else {
|
||||
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_settings, view -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
Uri uri = Uri.fromParts("package", AbsBaseActivity.this.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
startActivity(intent);
|
||||
})
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
}
|
||||
return;
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
final boolean hasPermissions = hasPermissions();
|
||||
if (hasPermissions != hadPermissions) {
|
||||
hadPermissions = hasPermissions;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
onHasPermissionsChanged(hasPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void onHasPermissionsChanged(boolean hasPermissions) {
|
||||
// implemented by sub classes
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_UP) {
|
||||
showOverflowMenu();
|
||||
return true;
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
protected void showOverflowMenu() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String[] getPermissionsToRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected View getSnackBarContainer() {
|
||||
return getWindow().getDecorView();
|
||||
}
|
||||
|
||||
private String getPermissionDeniedMessage() {
|
||||
return permissionDeniedMessage == null ? getString(R.string.permissions_denied)
|
||||
: permissionDeniedMessage;
|
||||
}
|
||||
|
||||
protected void setPermissionDeniedMessage(String message) {
|
||||
permissionDeniedMessage = message;
|
||||
}
|
||||
|
||||
protected void requestPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
requestPermissions(permissions, PERMISSION_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
for (String permission : permissions) {
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == PERMISSION_REQUEST) {
|
||||
for (int grantResult : grantResults) {
|
||||
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(AbsBaseActivity.this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
//User has deny from permission dialog
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_grant, view -> requestPermissions())
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
} else {
|
||||
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_settings, view -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
Uri uri = Uri.fromParts("package", AbsBaseActivity.this.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
startActivity(intent);
|
||||
})
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
hadPermissions = true;
|
||||
onHasPermissionsChanged(true);
|
||||
}
|
||||
}
|
||||
hadPermissions = true;
|
||||
onHasPermissionsChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||
import com.google.android.gms.cast.framework.CastContext;
|
||||
import com.google.android.gms.cast.framework.CastSession;
|
||||
import com.google.android.gms.cast.framework.SessionManagerListener;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.cast.WebServer;
|
||||
|
||||
public abstract class AbsCastActivity extends AbsBaseActivity {
|
||||
private static final String TAG = "AbsCastActivity";
|
||||
|
||||
public boolean playServicesAvailable = false;
|
||||
|
||||
private CastContext castContext;
|
||||
private SessionManagerListener<CastSession> sessionManagerListener;
|
||||
private CastSession castSession;
|
||||
private WebServer castServer;
|
||||
|
||||
private void setupCastListener() {
|
||||
sessionManagerListener = new SessionManagerListener<CastSession>() {
|
||||
|
||||
@Override
|
||||
public void onSessionEnded(CastSession session, int error) {
|
||||
onApplicationDisconnected();
|
||||
Log.i(TAG, "onSessionEnded: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResumed(CastSession session, boolean wasSuspended) {
|
||||
onApplicationConnected(session);
|
||||
Log.i(TAG, "onSessionResumed: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResumeFailed(CastSession session, int error) {
|
||||
onApplicationDisconnected();
|
||||
Log.i(TAG, "onSessionResumeFailed: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStarted(CastSession session, String sessionId) {
|
||||
onApplicationConnected(session);
|
||||
Log.i(TAG, "onSessionStarted: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStartFailed(CastSession session, int error) {
|
||||
onApplicationDisconnected();
|
||||
Log.i(TAG, "onSessionStartFailed: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStarting(CastSession session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionEnding(CastSession session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResuming(CastSession session, String sessionId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionSuspended(CastSession session, int reason) {
|
||||
}
|
||||
|
||||
private void onApplicationConnected(CastSession castSession) {
|
||||
AbsCastActivity.this.castSession = castSession;
|
||||
castServer = new WebServer(getApplicationContext());
|
||||
try {
|
||||
castServer.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
supportInvalidateOptionsMenu();
|
||||
showCastMiniController();
|
||||
}
|
||||
|
||||
private void onApplicationDisconnected() {
|
||||
if (castServer != null) {
|
||||
castServer.stop();
|
||||
}
|
||||
supportInvalidateOptionsMenu();
|
||||
hideCastMiniController();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
try {
|
||||
playServicesAvailable = GoogleApiAvailability
|
||||
.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
|
||||
if (playServicesAvailable)
|
||||
initCast();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
if (playServicesAvailable) {
|
||||
castContext.getSessionManager().addSessionManagerListener(sessionManagerListener, CastSession.class);
|
||||
}
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (playServicesAvailable) {
|
||||
castContext.getSessionManager().removeSessionManagerListener(
|
||||
sessionManagerListener, CastSession.class);
|
||||
}
|
||||
}
|
||||
|
||||
private void initCast() {
|
||||
setupCastListener();
|
||||
castContext = CastContext.getSharedInstance(this);
|
||||
castSession = castContext.getSessionManager().getCurrentCastSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_cast, menu);
|
||||
if (playServicesAvailable) {
|
||||
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, R.id.media_route_menu_item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void showCastMiniController() {
|
||||
//implement by overriding in activities
|
||||
}
|
||||
|
||||
public void hideCastMiniController() {
|
||||
//implement by overriding in activities
|
||||
}
|
||||
|
||||
public CastSession getCastSession() {
|
||||
return castSession;
|
||||
}
|
||||
}
|
|
@ -15,9 +15,9 @@ import android.support.annotation.Nullable;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.MEDIA_STORE_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.META_CHANGED;
|
||||
|
@ -27,7 +27,7 @@ import static code.name.monkey.retromusic.Constants.REPEAT_MODE_CHANGED;
|
|||
import static code.name.monkey.retromusic.Constants.SHUFFLE_MODE_CHANGED;
|
||||
|
||||
|
||||
public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements MusicServiceEventListener {
|
||||
public abstract class AbsMusicServiceActivity extends AbsCastActivity implements MusicServiceEventListener {
|
||||
public static final String TAG = AbsMusicServiceActivity.class.getSimpleName();
|
||||
|
||||
private final ArrayList<MusicServiceEventListener> mMusicServiceEventListeners = new ArrayList<>();
|
||||
|
@ -52,6 +52,7 @@ public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements
|
|||
});
|
||||
|
||||
setPermissionDeniedMessage(getString(R.string.permission_external_storage_denied));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -183,6 +184,7 @@ public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements
|
|||
return new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||
}
|
||||
|
||||
|
||||
private static final class MusicStateReceiver extends BroadcastReceiver {
|
||||
|
||||
private final WeakReference<AbsMusicServiceActivity> reference;
|
||||
|
|
|
@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.activities.base;
|
|||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.FloatRange;
|
||||
|
@ -12,6 +13,8 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewTreeObserver;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastSession;
|
||||
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState;
|
||||
|
||||
|
@ -38,7 +41,6 @@ import code.name.monkey.retromusic.ui.fragments.player.plain.PlainPlayerFragment
|
|||
import code.name.monkey.retromusic.ui.fragments.player.simple.SimplePlayerFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import code.name.monkey.retromusic.views.BottomNavigationViewEx;
|
||||
|
||||
public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivity implements
|
||||
SlidingUpPanelLayout.PanelSlideListener,
|
||||
|
@ -46,8 +48,6 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
|
||||
public static final String TAG = AbsSlidingMusicPanelActivity.class.getSimpleName();
|
||||
|
||||
@BindView(R.id.bottom_navigation)
|
||||
BottomNavigationViewEx bottomNavigationView;
|
||||
@BindView(R.id.sliding_layout)
|
||||
SlidingUpPanelLayout slidingUpPanelLayout;
|
||||
|
||||
|
@ -60,14 +60,33 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
private MiniPlayerFragment miniPlayerFragment;
|
||||
private ValueAnimator navigationBarColorAnimator;
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
CastSession castSession = getCastSession();
|
||||
if (castSession == null) {
|
||||
return;
|
||||
}
|
||||
//MusicPlayerRemote.pauseSong();
|
||||
//CastHelper.startCasting(castSession, MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(createContentView());
|
||||
ButterKnife.bind(this);
|
||||
choosFragmentForTheme();
|
||||
|
||||
findViewById(R.id.castMiniController).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startActivity(new Intent(AbsSlidingMusicPanelActivity.this, ExpandedControllerActivity.class));
|
||||
}
|
||||
});
|
||||
//noinspection ConstantConditions
|
||||
miniPlayerFragment.getView().setOnClickListener(v -> expandPanel());
|
||||
|
||||
slidingUpPanelLayout.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
|
@ -85,7 +104,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
}
|
||||
});
|
||||
|
||||
setupBottomView();
|
||||
//setupBottomView();
|
||||
slidingUpPanelLayout.addPanelSlideListener(this);
|
||||
|
||||
}
|
||||
|
@ -144,16 +163,16 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
.findFragmentById(R.id.mini_player_fragment);
|
||||
}
|
||||
|
||||
private void setupBottomView() {
|
||||
bottomNavigationView.setSelectedItemId(PreferenceUtil.getInstance(this).getLastPage());
|
||||
bottomNavigationView.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
bottomNavigationView.enableAnimation(false);
|
||||
bottomNavigationView.enableItemShiftingMode(false);
|
||||
bottomNavigationView.enableShiftingMode(false);
|
||||
bottomNavigationView.setTextSize(10f);
|
||||
bottomNavigationView.setTextVisibility(PreferenceUtil.getInstance(this).tabTitles());
|
||||
}
|
||||
|
||||
/* private void setupBottomView() {
|
||||
bottomNavigationView.setSelectedItemId(PreferenceUtil.getInstance(this).getLastPage());
|
||||
bottomNavigationView.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
bottomNavigationView.enableAnimation(false);
|
||||
bottomNavigationView.enableItemShiftingMode(false);
|
||||
bottomNavigationView.enableShiftingMode(false);
|
||||
bottomNavigationView.setTextSize(10f);
|
||||
bottomNavigationView.setTextVisibility(PreferenceUtil.getInstance(this).tabTitles());
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
@ -196,7 +215,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
|
||||
@Override
|
||||
public void onPanelSlide(View panel, @FloatRange(from = 0, to = 1) float slideOffset) {
|
||||
bottomNavigationView.setTranslationY(slideOffset * 400);
|
||||
//bottomNavigationView.setTranslationY(slideOffset * 400);
|
||||
setMiniPlayerAlphaProgress(slideOffset);
|
||||
//findViewById(R.id.player_fragment_container).setAlpha(slideOffset);
|
||||
}
|
||||
|
@ -317,35 +336,17 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
}
|
||||
|
||||
public void hideBottomBar(final boolean hide) {
|
||||
|
||||
int heightOfBar =
|
||||
getResources().getDimensionPixelSize(R.dimen.mini_player_height);
|
||||
int heightOfBarWithTabs =
|
||||
getResources().getDimensionPixelSize(R.dimen.mini_player_height_expanded);
|
||||
|
||||
if (hide) {
|
||||
slidingUpPanelLayout.setPanelHeight(0);
|
||||
collapsePanel();
|
||||
} else {
|
||||
if (!MusicPlayerRemote.getPlayingQueue().isEmpty()) {
|
||||
slidingUpPanelLayout.setPanelHeight(bottomNavigationView.getVisibility() == View.VISIBLE ?
|
||||
heightOfBarWithTabs : heightOfBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBottomBarVisibility(int gone) {
|
||||
if (bottomNavigationView != null) {
|
||||
//TransitionManager.beginDelayedTransition(bottomNavigationView);
|
||||
bottomNavigationView.setVisibility(gone);
|
||||
hideBottomBar(false);
|
||||
slidingUpPanelLayout.setPanelHeight(getResources().getDimensionPixelSize(R.dimen.mini_player_height));
|
||||
}
|
||||
}
|
||||
|
||||
protected View wrapSlidingMusicPanel(@LayoutRes int resId) {
|
||||
@SuppressLint("InflateParams")
|
||||
View slidingMusicPanelLayout = getLayoutInflater()
|
||||
.inflate(R.layout.sliding_music_panel_layout, null);
|
||||
View slidingMusicPanelLayout = getLayoutInflater().inflate(R.layout.sliding_music_panel_layout, null);
|
||||
ViewGroup contentContainer = slidingMusicPanelLayout.findViewById(R.id.content_container);
|
||||
getLayoutInflater().inflate(resId, contentContainer);
|
||||
return slidingMusicPanelLayout;
|
||||
|
@ -379,7 +380,7 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
navigationBarColorAnimator.addUpdateListener(animation -> {
|
||||
int playerFragmentColorDark = ColorUtil.darkenColor((Integer) animation.getAnimatedValue());
|
||||
|
||||
bottomNavigationView.setBackgroundColor(playerFragmentColorDark);
|
||||
//bottomNavigationView.setBackgroundColor(playerFragmentColorDark);
|
||||
miniPlayerFragment.setColor(playerFragmentColorDark);
|
||||
AbsSlidingMusicPanelActivity.super.setNavigationbarColor(playerFragmentColorDark);
|
||||
|
||||
|
@ -417,9 +418,6 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
return playerFragment;
|
||||
}
|
||||
|
||||
public BottomNavigationViewEx getBottomNavigationView() {
|
||||
return bottomNavigationView;
|
||||
}
|
||||
|
||||
public SlidingUpPanelLayout.PanelState getPanelState() {
|
||||
return slidingUpPanelLayout == null ? null : slidingUpPanelLayout.getPanelState();
|
||||
|
@ -432,4 +430,18 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
|||
public void expandPanel() {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCastMiniController() {
|
||||
super.hideCastMiniController();
|
||||
hideBottomBar(false);
|
||||
findViewById(R.id.castMiniController).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCastMiniController() {
|
||||
super.showCastMiniController();
|
||||
hideBottomBar(true);
|
||||
findViewById(R.id.castMiniController).setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,10 @@ import android.support.v4.content.ContextCompat;
|
|||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import code.name.monkey.appthemehelper.ATH;
|
||||
import code.name.monkey.appthemehelper.ATHActivity;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialDialogsUtil;
|
||||
|
@ -22,189 +23,189 @@ import code.name.monkey.retromusic.R;
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public abstract class AbsThemeActivity extends ATHToolbarActivity implements Runnable {
|
||||
public abstract class AbsThemeActivity extends ATHActivity implements Runnable {
|
||||
|
||||
private Handler handler = new Handler();
|
||||
private Handler handler = new Handler();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(PreferenceUtil.getInstance(this).getGeneralTheme());
|
||||
hideStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(PreferenceUtil.getInstance(this).getGeneralTheme());
|
||||
hideStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this);
|
||||
|
||||
changeBackgroundShape();
|
||||
setImmersiveFullscreen();
|
||||
registerSystemUiVisibility();
|
||||
toggleScreenOn();
|
||||
}
|
||||
|
||||
private void toggleScreenOn() {
|
||||
if (PreferenceUtil.getInstance(this).isScreenOnEnabled()) {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
} else {
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
hideStatusBar();
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 300);
|
||||
} else {
|
||||
handler.removeCallbacks(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideStatusBar() {
|
||||
hideStatusBar(PreferenceUtil.getInstance(this).getFullScreenMode());
|
||||
}
|
||||
|
||||
private void hideStatusBar(boolean fullscreen) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
statusBar.setVisibility(fullscreen ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void changeBackgroundShape() {
|
||||
Drawable background = PreferenceUtil.getInstance(this).isRoundCorners() ?
|
||||
ContextCompat.getDrawable(this, R.drawable.round_window)
|
||||
: ContextCompat.getDrawable(this, R.drawable.square_window);
|
||||
background = TintHelper.createTintedDrawable(background, ThemeStore.primaryColor(this));
|
||||
getWindow().setBackgroundDrawable(background);
|
||||
}
|
||||
|
||||
protected void setDrawUnderStatusBar(boolean drawUnderStatusbar) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
RetroUtil.setAllowDrawUnderStatusBar(getWindow());
|
||||
} else if (VersionUtils.hasKitKat()) {
|
||||
RetroUtil.setStatusBarTranslucent(getWindow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
|
||||
* Lollipop if no such view is found it will set the statusbar color using the native method.
|
||||
*
|
||||
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
||||
*/
|
||||
public void setStatusbarColor(int color) {
|
||||
if (VersionUtils.hasKitKat()) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
statusBar.setBackgroundColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
} else {
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||
getWindow().setStatusBarColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatusbarColorAuto() {
|
||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||
setStatusbarColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColor(@ColorInt int color) {
|
||||
ATH.setTaskDescriptionColor(this, color);
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColorAuto() {
|
||||
setTaskDescriptionColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setNavigationbarColor(int color) {
|
||||
if (ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setNavigationbarColor(this, color);
|
||||
} else {
|
||||
ATH.setNavigationbarColor(this, Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
public void setNavigationbarColorAuto() {
|
||||
setNavigationbarColor(ThemeStore.navigationBarColor(this));
|
||||
}
|
||||
|
||||
public void setLightStatusbar(boolean enabled) {
|
||||
ATH.setLightStatusbar(this, enabled);
|
||||
}
|
||||
|
||||
public void setLightStatusbarAuto(int bgColor) {
|
||||
setLightStatusbar(ColorUtil.isColorLight(bgColor));
|
||||
}
|
||||
|
||||
public void setLightNavigationBar(boolean enabled) {
|
||||
if (!ATHUtil.isWindowBackgroundDark(this) && ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setLightNavigationbar(this, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
|
||||
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||
changeBackgroundShape();
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void unregisterSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(null);
|
||||
}
|
||||
|
||||
public void setImmersiveFullscreen() {
|
||||
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
if (PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
registerSystemUiVisibility();
|
||||
toggleScreenOn();
|
||||
}
|
||||
}
|
||||
|
||||
public void exitFullscreen() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
handler.removeCallbacks(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterSystemUiVisibility();
|
||||
exitFullscreen();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 500);
|
||||
private void toggleScreenOn() {
|
||||
if (PreferenceUtil.getInstance(this).isScreenOnEnabled()) {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
} else {
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
hideStatusBar();
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 300);
|
||||
} else {
|
||||
handler.removeCallbacks(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideStatusBar() {
|
||||
hideStatusBar(PreferenceUtil.getInstance(this).getFullScreenMode());
|
||||
}
|
||||
|
||||
private void hideStatusBar(boolean fullscreen) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
statusBar.setVisibility(fullscreen ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void changeBackgroundShape() {
|
||||
Drawable background = PreferenceUtil.getInstance(this).isRoundCorners() ?
|
||||
ContextCompat.getDrawable(this, R.drawable.round_window)
|
||||
: ContextCompat.getDrawable(this, R.drawable.square_window);
|
||||
background = TintHelper.createTintedDrawable(background, ThemeStore.primaryColor(this));
|
||||
getWindow().setBackgroundDrawable(background);
|
||||
}
|
||||
|
||||
protected void setDrawUnderStatusBar(boolean drawUnderStatusbar) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
RetroUtil.setAllowDrawUnderStatusBar(getWindow());
|
||||
} else if (VersionUtils.hasKitKat()) {
|
||||
RetroUtil.setStatusBarTranslucent(getWindow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
|
||||
* Lollipop if no such view is found it will set the statusbar color using the native method.
|
||||
*
|
||||
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
||||
*/
|
||||
public void setStatusbarColor(int color) {
|
||||
if (VersionUtils.hasKitKat()) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
statusBar.setBackgroundColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
} else {
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||
getWindow().setStatusBarColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatusbarColorAuto() {
|
||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||
setStatusbarColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColor(@ColorInt int color) {
|
||||
ATH.setTaskDescriptionColor(this, color);
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColorAuto() {
|
||||
setTaskDescriptionColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setNavigationbarColor(int color) {
|
||||
if (ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setNavigationbarColor(this, color);
|
||||
} else {
|
||||
ATH.setNavigationbarColor(this, Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
public void setNavigationbarColorAuto() {
|
||||
setNavigationbarColor(ThemeStore.navigationBarColor(this));
|
||||
}
|
||||
|
||||
public void setLightStatusbar(boolean enabled) {
|
||||
ATH.setLightStatusbar(this, enabled);
|
||||
}
|
||||
|
||||
public void setLightStatusbarAuto(int bgColor) {
|
||||
setLightStatusbar(ColorUtil.isColorLight(bgColor));
|
||||
}
|
||||
|
||||
public void setLightNavigationBar(boolean enabled) {
|
||||
if (!ATHUtil.isWindowBackgroundDark(this) && ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setLightNavigationbar(this, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
|
||||
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void unregisterSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(null);
|
||||
}
|
||||
|
||||
public void setImmersiveFullscreen() {
|
||||
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
if (PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
}
|
||||
}
|
||||
|
||||
public void exitFullscreen() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
handler.removeCallbacks(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterSystemUiVisibility();
|
||||
exitFullscreen();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 500);
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ import java.util.Map;
|
|||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
|
|
@ -7,16 +7,9 @@ import android.graphics.Bitmap;
|
|||
import android.media.MediaScannerConnection;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
|
@ -29,135 +22,146 @@ import org.jaudiotagger.tag.TagException;
|
|||
import org.jaudiotagger.tag.images.Artwork;
|
||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
public class WriteTagsAsyncTask extends
|
||||
DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
|
||||
DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
|
||||
|
||||
private Context applicationContext;
|
||||
private Context applicationContext;
|
||||
|
||||
public WriteTagsAsyncTask(Context context) {
|
||||
super(context);
|
||||
applicationContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
LoadingInfo info = params[0];
|
||||
|
||||
Artwork artwork = null;
|
||||
File albumArtFile = null;
|
||||
if (info.artworkInfo != null && info.artworkInfo.artwork != null) {
|
||||
try {
|
||||
albumArtFile = MusicUtil.createAlbumArtFile().getCanonicalFile();
|
||||
info.artworkInfo.artwork
|
||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
boolean wroteArtwork = false;
|
||||
boolean deletedArtwork = false;
|
||||
for (String filePath : info.filePaths) {
|
||||
publishProgress(++counter, info.filePaths.size());
|
||||
try {
|
||||
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||
|
||||
if (info.fieldKeyValueMap != null) {
|
||||
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
|
||||
try {
|
||||
tag.setField(entry.getKey(), entry.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info.artworkInfo != null) {
|
||||
if (info.artworkInfo.artwork == null) {
|
||||
tag.deleteArtworkField();
|
||||
deletedArtwork = true;
|
||||
} else if (artwork != null) {
|
||||
tag.deleteArtworkField();
|
||||
tag.setField(artwork);
|
||||
wroteArtwork = true;
|
||||
}
|
||||
}
|
||||
|
||||
audioFile.commit();
|
||||
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
if (wroteArtwork) {
|
||||
MusicUtil.insertAlbumArt(context, info.artworkInfo.albumId, albumArtFile.getPath());
|
||||
} else if (deletedArtwork) {
|
||||
MusicUtil.deleteAlbumArt(context, info.artworkInfo.albumId);
|
||||
}
|
||||
}
|
||||
|
||||
return info.filePaths.toArray(new String[info.filePaths.size()]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
public WriteTagsAsyncTask(Context context) {
|
||||
super(context);
|
||||
applicationContext = context;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] toBeScanned) {
|
||||
super.onPostExecute(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
@Override
|
||||
protected String[] doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
LoadingInfo info = params[0];
|
||||
|
||||
@Override
|
||||
protected void onCancelled(String[] toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
Artwork artwork = null;
|
||||
File albumArtFile = null;
|
||||
if (info.artworkInfo != null && info.artworkInfo.artwork != null) {
|
||||
try {
|
||||
albumArtFile = MusicUtil.createAlbumArtFile().getCanonicalFile();
|
||||
info.artworkInfo.artwork
|
||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void scan(String[] toBeScanned) {
|
||||
Context context = getContext();
|
||||
MediaScannerConnection.scanFile(applicationContext, toBeScanned, null,
|
||||
context instanceof Activity ? new UpdateToastMediaScannerCompletionListener(
|
||||
(Activity) context, toBeScanned) : null);
|
||||
}
|
||||
int counter = 0;
|
||||
boolean wroteArtwork = false;
|
||||
boolean deletedArtwork = false;
|
||||
for (String filePath : info.filePaths) {
|
||||
publishProgress(++counter, info.filePaths.size());
|
||||
try {
|
||||
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.saving_changes)
|
||||
.cancelable(false)
|
||||
.progress(false, 0)
|
||||
.build();
|
||||
}
|
||||
if (info.fieldKeyValueMap != null) {
|
||||
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
|
||||
try {
|
||||
tag.setField(entry.getKey(), entry.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||
super.onProgressUpdate(dialog, values);
|
||||
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||
((MaterialDialog) dialog).setProgress(values[0]);
|
||||
}
|
||||
if (info.artworkInfo != null) {
|
||||
if (info.artworkInfo.artwork == null) {
|
||||
tag.deleteArtworkField();
|
||||
deletedArtwork = true;
|
||||
} else if (artwork != null) {
|
||||
tag.deleteArtworkField();
|
||||
tag.setField(artwork);
|
||||
wroteArtwork = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
audioFile.commit();
|
||||
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<String> filePaths;
|
||||
@Nullable
|
||||
final Map<FieldKey, String> fieldKeyValueMap;
|
||||
@Nullable
|
||||
private AbsTagEditorActivity.ArtworkInfo artworkInfo;
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
if (wroteArtwork) {
|
||||
MusicUtil.insertAlbumArt(context, info.artworkInfo.albumId, albumArtFile.getPath());
|
||||
} else if (deletedArtwork) {
|
||||
MusicUtil.deleteAlbumArt(context, info.artworkInfo.albumId);
|
||||
}
|
||||
}
|
||||
|
||||
public LoadingInfo(Collection<String> filePaths,
|
||||
@Nullable Map<FieldKey, String> fieldKeyValueMap,
|
||||
@Nullable AbsTagEditorActivity.ArtworkInfo artworkInfo) {
|
||||
this.filePaths = filePaths;
|
||||
this.fieldKeyValueMap = fieldKeyValueMap;
|
||||
this.artworkInfo = artworkInfo;
|
||||
return info.filePaths.toArray(new String[info.filePaths.size()]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] toBeScanned) {
|
||||
super.onPostExecute(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(String[] toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
private void scan(String[] toBeScanned) {
|
||||
Context context = getContext();
|
||||
MediaScannerConnection.scanFile(applicationContext, toBeScanned, null,
|
||||
context instanceof Activity ? new UpdateToastMediaScannerCompletionListener(
|
||||
(Activity) context, toBeScanned) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.saving_changes)
|
||||
.cancelable(false)
|
||||
.progress(false, 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||
super.onProgressUpdate(dialog, values);
|
||||
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||
((MaterialDialog) dialog).setProgress(values[0]);
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
|
||||
final Collection<String> filePaths;
|
||||
@Nullable
|
||||
final Map<FieldKey, String> fieldKeyValueMap;
|
||||
@Nullable
|
||||
private AbsTagEditorActivity.ArtworkInfo artworkInfo;
|
||||
|
||||
public LoadingInfo(Collection<String> filePaths,
|
||||
@Nullable Map<FieldKey, String> fieldKeyValueMap,
|
||||
@Nullable AbsTagEditorActivity.ArtworkInfo artworkInfo) {
|
||||
this.filePaths = filePaths;
|
||||
this.fieldKeyValueMap = fieldKeyValueMap;
|
||||
this.artworkInfo = artworkInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,19 +9,19 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
@ -57,7 +57,7 @@ public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == HEADER)
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.sub_header, parent, false), viewType);
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false), viewType);
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.view.ViewGroup;
|
|||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -22,6 +21,7 @@ import java.text.DecimalFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
|
@ -35,10 +35,10 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
private static final int FOLDER = 1;
|
||||
|
||||
private final AppCompatActivity activity;
|
||||
private List<File> dataSet;
|
||||
private final int itemLayoutRes;
|
||||
@Nullable
|
||||
private final Callbacks callbacks;
|
||||
private List<File> dataSet;
|
||||
|
||||
public SongFileAdapter(@NonNull AppCompatActivity activity, @NonNull List<File> songFiles, @LayoutRes int itemLayoutRes, @Nullable Callbacks callback, @Nullable CabHolder cabHolder) {
|
||||
super(activity, cabHolder, R.menu.menu_media_selection);
|
||||
|
@ -49,6 +49,13 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
public static String readableFileSize(long size) {
|
||||
if (size <= 0) return size + " B";
|
||||
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
|
||||
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
||||
return new DecimalFormat("#,##0.##").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return dataSet.get(position).isDirectory() ? FOLDER : FILE;
|
||||
|
@ -64,13 +71,14 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int index) {
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int index) {
|
||||
final File file = dataSet.get(index);
|
||||
|
||||
holder.itemView.setActivated(isChecked(file));
|
||||
|
@ -128,13 +136,6 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
}
|
||||
}
|
||||
|
||||
public static String readableFileSize(long size) {
|
||||
if (size <= 0) return size + " B";
|
||||
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
|
||||
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
||||
return new DecimalFormat("#,##0.##").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
|
@ -162,6 +163,14 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
return String.valueOf(dataSet.get(position).getName().charAt(0)).toUpperCase();
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
void onFileSelected(File file);
|
||||
|
||||
void onFileMenuClicked(File file, View view);
|
||||
|
||||
void onMultipleItemAction(MenuItem item, ArrayList<File> files);
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
|
@ -203,12 +212,4 @@ public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewH
|
|||
return position >= 0 && position < dataSet.size();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
void onFileSelected(File file);
|
||||
|
||||
void onFileMenuClicked(File file, View view);
|
||||
|
||||
void onMultipleItemAction(MenuItem item, ArrayList<File> files);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.album;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
|
|
|
@ -7,64 +7,66 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.ui.adapter.playlist.AddToPlaylist.ViewHolder;
|
||||
import code.name.monkey.retromusic.util.PlaylistsUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
public class AddToPlaylist extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
private Activity activity;
|
||||
private ArrayList<Playlist> playlists;
|
||||
private int itemLayoutRes;
|
||||
private ArrayList<Song> songs;
|
||||
private Dialog dialog;
|
||||
private Activity activity;
|
||||
private ArrayList<Playlist> playlists;
|
||||
private int itemLayoutRes;
|
||||
private ArrayList<Song> songs;
|
||||
private Dialog dialog;
|
||||
|
||||
public AddToPlaylist(Activity activity,
|
||||
ArrayList<Playlist> playlists, int itemLayoutRes,
|
||||
ArrayList<Song> songs, Dialog dialog) {
|
||||
this.activity = activity;
|
||||
this.playlists = playlists;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.songs = songs;
|
||||
this.dialog = dialog;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Playlist playlist = playlists.get(position);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(playlist.name);
|
||||
public AddToPlaylist(Activity activity,
|
||||
ArrayList<Playlist> playlists, int itemLayoutRes,
|
||||
ArrayList<Song> songs, Dialog dialog) {
|
||||
this.activity = activity;
|
||||
this.playlists = playlists;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.songs = songs;
|
||||
this.dialog = dialog;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return playlists.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
PlaylistsUtil.addToPlaylist(activity, songs, playlists.get(getAdapterPosition()).id, true);
|
||||
dialog.dismiss();
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Playlist playlist = playlists.get(position);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(playlist.name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return playlists.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
PlaylistsUtil.addToPlaylist(activity, songs, playlists.get(getAdapterPosition()).id, true);
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
|
|||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags;
|
||||
import code.name.monkey.retromusic.model.PlaylistSong;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -20,6 +18,8 @@ import java.util.List;
|
|||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.PlaylistSong;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
|
|
|
@ -5,74 +5,76 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class ShuffleButtonSongAdapter extends AbsOffsetSongAdapter {
|
||||
|
||||
public ShuffleButtonSongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final SongAdapter.ViewHolder holder, int position) {
|
||||
if (holder.getItemViewType() == OFFSET_ITEM) {
|
||||
int accentColor = ThemeStore.accentColor(activity);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(activity.getResources().getString(R.string.action_shuffle_all));
|
||||
holder.title.setTextColor(accentColor);
|
||||
/*((GradientTextView) holder.title).setLinearGradient(ThemeStore.accentColor(activity),
|
||||
PhonographColorUtil.getMatColor(activity, "A400"), GradientTextView.LG_VERTICAL);
|
||||
*/
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
holder.menu.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.image != null) {
|
||||
final int padding =
|
||||
activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin) / 2;
|
||||
holder.image.setPadding(padding, padding, padding, padding);
|
||||
holder.image.setColorFilter(accentColor);
|
||||
holder.image.setImageResource(R.drawable.ic_shuffle_white_24dp);
|
||||
}
|
||||
if (holder.separator != null) {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends AbsOffsetSongAdapter.ViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
public ShuffleButtonSongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getItemViewType() == OFFSET_ITEM) {
|
||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true);
|
||||
return;
|
||||
}
|
||||
super.onClick(v);
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final SongAdapter.ViewHolder holder, int position) {
|
||||
if (holder.getItemViewType() == OFFSET_ITEM) {
|
||||
int accentColor = ThemeStore.accentColor(activity);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(activity.getResources().getString(R.string.action_shuffle_all));
|
||||
holder.title.setTextColor(accentColor);
|
||||
/*((GradientTextView) holder.title).setLinearGradient(ThemeStore.accentColor(activity),
|
||||
PhonographColorUtil.getMatColor(activity, "A400"), GradientTextView.LG_VERTICAL);
|
||||
*/
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
holder.menu.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.image != null) {
|
||||
final int padding =
|
||||
activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin) / 2;
|
||||
holder.image.setPadding(padding, padding, padding, padding);
|
||||
holder.image.setColorFilter(accentColor);
|
||||
holder.image.setImageResource(R.drawable.ic_shuffle_white_24dp);
|
||||
}
|
||||
if (holder.separator != null) {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends AbsOffsetSongAdapter.ViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getItemViewType() == OFFSET_ITEM) {
|
||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true);
|
||||
return;
|
||||
}
|
||||
super.onClick(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false);
|
||||
return createViewHolder(view);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.view.ViewGroup;
|
|||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -26,151 +27,162 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
|||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
|
||||
|
||||
public class MiniPlayerFragment extends AbsMusicServiceFragment implements
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
public class MiniPlayerFragment extends AbsMusicServiceFragment implements MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
@BindView(R.id.mini_player_title)
|
||||
TextView miniPlayerTitle;
|
||||
@BindView(R.id.mini_player_play_pause_button)
|
||||
ImageView miniPlayerPlayPauseButton;
|
||||
@BindView(R.id.progress_bar)
|
||||
MaterialProgressBar progressBar;
|
||||
@BindView(R.id.mini_player_title)
|
||||
TextView miniPlayerTitle;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable miniPlayerPlayPauseDrawable;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
@BindView(R.id.mini_player_play_pause_button)
|
||||
ImageView miniPlayerPlayPauseButton;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
@BindView(R.id.action_next)
|
||||
View next;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.fragment_mini_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
@BindView(R.id.action_prev)
|
||||
View previous;
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
view.setBackgroundColor(ThemeStore.primaryColor(getContext()));
|
||||
view.setOnTouchListener(new FlingPlayBackController(getActivity()));
|
||||
setUpMiniPlayer();
|
||||
}
|
||||
@BindView(R.id.progress_bar)
|
||||
MaterialProgressBar progressBar;
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable miniPlayerPlayPauseDrawable;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@SuppressWarnings({"ConstantConditions"})
|
||||
private void setUpMiniPlayer() {
|
||||
setUpPlayPauseButton();
|
||||
progressBar.setProgressTintList(ColorStateList.valueOf(ThemeStore.accentColor(getActivity())));
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
//noinspection ConstantConditions
|
||||
miniPlayerPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
miniPlayerPlayPauseButton.setImageDrawable(miniPlayerPlayPauseDrawable);
|
||||
miniPlayerPlayPauseButton.setColorFilter(ATHUtil.resolveColor(getActivity(),
|
||||
R.attr.iconColor,
|
||||
ThemeStore.textColorSecondary(getActivity())), PorterDuff.Mode.SRC_IN);
|
||||
miniPlayerPlayPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
}
|
||||
|
||||
private void updateSongTitle() {
|
||||
miniPlayerTitle.setText(MusicPlayerRemote.getCurrentSong().title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateSongTitle();
|
||||
updatePlayPauseDrawableState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateSongTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressBar.setMax(total);
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", progress);
|
||||
animator.setDuration(1000);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
miniPlayerPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
miniPlayerPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(int playerFragmentColor) {
|
||||
//noinspection ConstantConditions
|
||||
getView().setBackgroundColor(playerFragmentColor);
|
||||
}
|
||||
|
||||
public static class FlingPlayBackController implements View.OnTouchListener {
|
||||
|
||||
GestureDetector flingPlayBackController;
|
||||
|
||||
public FlingPlayBackController(Context context) {
|
||||
flingPlayBackController = new GestureDetector(context,
|
||||
new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||
float velocityY) {
|
||||
if (Math.abs(velocityX) > Math.abs(velocityY)) {
|
||||
if (velocityX < 0) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
return true;
|
||||
} else if (velocityX > 0) {
|
||||
MusicPlayerRemote.playPreviousSong();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return flingPlayBackController.onTouchEvent(event);
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.fragment_mini_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
view.setBackgroundColor(ThemeStore.primaryColor(getContext()));
|
||||
view.setOnTouchListener(new FlingPlayBackController(getActivity()));
|
||||
setUpMiniPlayer();
|
||||
|
||||
next.setVisibility(PreferenceUtil.getInstance(getContext()).isExtraMiniExtraControls() ? View.VISIBLE : View.GONE);
|
||||
previous.setVisibility(PreferenceUtil.getInstance(getContext()).isExtraMiniExtraControls() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions"})
|
||||
private void setUpMiniPlayer() {
|
||||
setUpPlayPauseButton();
|
||||
progressBar.setProgressTintList(ColorStateList.valueOf(ThemeStore.accentColor(getActivity())));
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
//noinspection ConstantConditions
|
||||
miniPlayerPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
miniPlayerPlayPauseButton.setImageDrawable(miniPlayerPlayPauseDrawable);
|
||||
miniPlayerPlayPauseButton.setColorFilter(ATHUtil.resolveColor(getActivity(),
|
||||
R.attr.iconColor,
|
||||
ThemeStore.textColorSecondary(getActivity())), PorterDuff.Mode.SRC_IN);
|
||||
miniPlayerPlayPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
}
|
||||
|
||||
private void updateSongTitle() {
|
||||
miniPlayerTitle.setText(MusicPlayerRemote.getCurrentSong().title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateSongTitle();
|
||||
updatePlayPauseDrawableState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateSongTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressBar.setMax(total);
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", progress);
|
||||
animator.setDuration(1000);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
miniPlayerPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
miniPlayerPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(int playerFragmentColor) {
|
||||
//noinspection ConstantConditions
|
||||
getView().setBackgroundColor(playerFragmentColor);
|
||||
}
|
||||
|
||||
public static class FlingPlayBackController implements View.OnTouchListener {
|
||||
|
||||
GestureDetector flingPlayBackController;
|
||||
|
||||
public FlingPlayBackController(Context context) {
|
||||
flingPlayBackController = new GestureDetector(context,
|
||||
new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||
float velocityY) {
|
||||
if (Math.abs(velocityX) > Math.abs(velocityY)) {
|
||||
if (velocityX < 0) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
return true;
|
||||
} else if (velocityX > 0) {
|
||||
MusicPlayerRemote.playPreviousSong();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return flingPlayBackController.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,33 @@ package code.name.monkey.retromusic.ui.fragments;
|
|||
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public enum NowPlayingScreen {
|
||||
NORMAL(R.string.normal, R.drawable.np_normal, 0),
|
||||
FLAT(R.string.flat, R.drawable.np_flat, 1),
|
||||
FULL(R.string.full, R.drawable.np_full, 2),
|
||||
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||
COLOR(R.string.color, R.drawable.np_color, 5),
|
||||
CARD(R.string.card, R.drawable.np_card, 6),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||
MATERIAL(R.string.material, R.drawable.np_material, 11);
|
||||
NORMAL(R.string.normal, R.drawable.np_normal, 0),
|
||||
FLAT(R.string.flat, R.drawable.np_flat, 1),
|
||||
FULL(R.string.full, R.drawable.np_full, 2),
|
||||
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||
COLOR(R.string.color, R.drawable.np_color, 5),
|
||||
CARD(R.string.card, R.drawable.np_card, 6),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||
MATERIAL(R.string.material, R.drawable.np_material, 11);
|
||||
|
||||
@StringRes
|
||||
public final int titleRes;
|
||||
@DrawableRes
|
||||
public final int drawableResId;
|
||||
public final int id;
|
||||
@StringRes
|
||||
public final int titleRes;
|
||||
@DrawableRes
|
||||
public final int drawableResId;
|
||||
public final int id;
|
||||
|
||||
NowPlayingScreen(@StringRes int titleRes, @DrawableRes int drawableResId, int id) {
|
||||
this.titleRes = titleRes;
|
||||
this.drawableResId = drawableResId;
|
||||
this.id = id;
|
||||
}
|
||||
NowPlayingScreen(@StringRes int titleRes, @DrawableRes int drawableResId, int id) {
|
||||
this.titleRes = titleRes;
|
||||
this.drawableResId = drawableResId;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -16,128 +22,124 @@ import code.name.monkey.retromusic.R;
|
|||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
public class PlayingQueueFragment extends AbsMusicServiceFragment {
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView mRecyclerView;
|
||||
Unbinder unbinder;
|
||||
private RecyclerView.Adapter mWrappedAdapter;
|
||||
private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter mPlayingQueueAdapter;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView mRecyclerView;
|
||||
Unbinder unbinder;
|
||||
private RecyclerView.Adapter mWrappedAdapter;
|
||||
private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter mPlayingQueueAdapter;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_main_activity_recycler_view, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
mPlayingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_list,
|
||||
false,
|
||||
null);
|
||||
mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mPlayingQueueAdapter);
|
||||
|
||||
mLayoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mRecyclerView.setAdapter(mWrappedAdapter);
|
||||
mRecyclerView.setItemAnimator(animator);
|
||||
mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
//updateCurrentSong();
|
||||
//updateIsFavorite();
|
||||
updateQueuePosition();
|
||||
//updateLyrics();
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
mPlayingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
mPlayingQueueAdapter
|
||||
.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
mRecyclerView.stopScroll();
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.release();
|
||||
mRecyclerViewDragDropManager = null;
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_main_activity_recycler_view, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
if (mRecyclerView != null) {
|
||||
mRecyclerView.setItemAnimator(null);
|
||||
mRecyclerView.setAdapter(null);
|
||||
mRecyclerView = null;
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
if (mWrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(mWrappedAdapter);
|
||||
mWrappedAdapter = null;
|
||||
private void setUpRecyclerView() {
|
||||
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
mPlayingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_list,
|
||||
false,
|
||||
null);
|
||||
mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mPlayingQueueAdapter);
|
||||
|
||||
mLayoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mRecyclerView.setAdapter(mWrappedAdapter);
|
||||
mRecyclerView.setItemAnimator(animator);
|
||||
mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
//updateCurrentSong();
|
||||
//updateIsFavorite();
|
||||
updateQueuePosition();
|
||||
//updateLyrics();
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
mPlayingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
mPlayingQueueAdapter
|
||||
.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
mRecyclerView.stopScroll();
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.release();
|
||||
mRecyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (mRecyclerView != null) {
|
||||
mRecyclerView.setItemAnimator(null);
|
||||
mRecyclerView.setAdapter(null);
|
||||
mRecyclerView = null;
|
||||
}
|
||||
|
||||
if (mWrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(mWrappedAdapter);
|
||||
mWrappedAdapter = null;
|
||||
}
|
||||
mPlayingQueueAdapter = null;
|
||||
mLayoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
mPlayingQueueAdapter = null;
|
||||
mLayoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment;
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -19,143 +22,148 @@ import code.name.monkey.appthemehelper.ThemeStore;
|
|||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
|
||||
public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView.Adapter, LM extends RecyclerView.LayoutManager> extends
|
||||
AbsLibraryPagerFragment implements OnOffsetChangedListener {
|
||||
AbsLibraryPagerFragment implements OnOffsetChangedListener {
|
||||
|
||||
public static final String TAG = AbsLibraryPagerRecyclerViewFragment.class.getSimpleName();
|
||||
@BindView(R.id.container)
|
||||
ViewGroup container;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
public static final String TAG = AbsLibraryPagerRecyclerViewFragment.class.getSimpleName();
|
||||
@BindView(R.id.container)
|
||||
ViewGroup container;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private A adapter;
|
||||
private LM layoutManager;
|
||||
private Unbinder unbinder;
|
||||
private A adapter;
|
||||
private LM layoutManager;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(getLayoutRes(), container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
getLibraryFragment().addOnAppBarOffsetChangedListener(this);
|
||||
initLayoutManager();
|
||||
initAdapter();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView instanceof FastScrollRecyclerView) {
|
||||
//noinspection ConstantConditions
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(),
|
||||
((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity()));
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(getLayoutRes(), container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
super.onQueueChanged();
|
||||
checkForPadding();
|
||||
}
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
getLibraryFragment().addOnAppBarOffsetChangedListener(this);
|
||||
initLayoutManager();
|
||||
initAdapter();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
checkForPadding();
|
||||
}
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView instanceof FastScrollRecyclerView) {
|
||||
//noinspection ConstantConditions
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(),
|
||||
((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity()));
|
||||
}
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
getLibraryFragment().addAppbarLayoutElevation(recyclerView.canScrollVertically(RecyclerView.NO_POSITION) ? 6f : 0f);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkForPadding() {
|
||||
int height = (MusicPlayerRemote.getPlayingQueue().isEmpty() ? getResources()
|
||||
.getDimensionPixelSize(R.dimen.mini_player_height) : 0);
|
||||
recyclerView.setPadding(0, 0, 0, height);
|
||||
}
|
||||
|
||||
protected void invalidateLayoutManager() {
|
||||
initLayoutManager();
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
}
|
||||
|
||||
protected void invalidateAdapter() {
|
||||
initAdapter();
|
||||
checkIsEmpty();
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void initAdapter() {
|
||||
adapter = createAdapter();
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
super.onQueueChanged();
|
||||
checkForPadding();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void initLayoutManager() {
|
||||
layoutManager = createLayoutManager();
|
||||
}
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
checkForPadding();
|
||||
}
|
||||
|
||||
protected A getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
private void checkForPadding() {
|
||||
int height = (MusicPlayerRemote.getPlayingQueue().isEmpty() ? getResources()
|
||||
.getDimensionPixelSize(R.dimen.mini_player_height) : 0);
|
||||
recyclerView.setPadding(0, 0, 0, height);
|
||||
}
|
||||
|
||||
protected LM getLayoutManager() {
|
||||
return layoutManager;
|
||||
}
|
||||
protected void invalidateLayoutManager() {
|
||||
initLayoutManager();
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
}
|
||||
|
||||
protected RecyclerView getRecyclerView() {
|
||||
return recyclerView;
|
||||
}
|
||||
protected void invalidateAdapter() {
|
||||
initAdapter();
|
||||
checkIsEmpty();
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
public ViewGroup getContainer() {
|
||||
return container;
|
||||
}
|
||||
private void initAdapter() {
|
||||
adapter = createAdapter();
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
checkForPadding();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
|
||||
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
|
||||
container.getPaddingRight(), getLibraryFragment().getTotalAppBarScrollingRange() + i);
|
||||
}
|
||||
private void initLayoutManager() {
|
||||
layoutManager = createLayoutManager();
|
||||
}
|
||||
|
||||
private void checkIsEmpty() {
|
||||
empty.setText(getEmptyMessage());
|
||||
empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
protected A getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty;
|
||||
}
|
||||
protected LM getLayoutManager() {
|
||||
return layoutManager;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected int getLayoutRes() {
|
||||
return R.layout.fragment_main_activity_recycler_view;
|
||||
}
|
||||
protected RecyclerView getRecyclerView() {
|
||||
return recyclerView;
|
||||
}
|
||||
|
||||
protected abstract LM createLayoutManager();
|
||||
public ViewGroup getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected abstract A createAdapter();
|
||||
@Override
|
||||
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
|
||||
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
|
||||
container.getPaddingRight(), getLibraryFragment().getTotalAppBarScrollingRange() + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
getLibraryFragment().removeOnAppBarOffsetChangedListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
private void checkIsEmpty() {
|
||||
empty.setText(getEmptyMessage());
|
||||
empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@StringRes
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected int getLayoutRes() {
|
||||
return R.layout.fragment_main_activity_recycler_view;
|
||||
}
|
||||
|
||||
protected abstract LM createLayoutManager();
|
||||
|
||||
@NonNull
|
||||
protected abstract A createAdapter();
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
getLibraryFragment().removeOnAppBarOffsetChangedListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ public abstract class AbsMainActivityFragment extends AbsMusicServiceFragment {
|
|||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
getMainActivity().setNavigationbarColorAuto();
|
||||
getMainActivity().setLightNavigationBar(true);
|
||||
getMainActivity().setTaskDescriptionColorAuto();
|
||||
|
@ -39,7 +38,7 @@ public abstract class AbsMainActivityFragment extends AbsMusicServiceFragment {
|
|||
statusBar.setBackgroundColor(color);
|
||||
getMainActivity().setLightStatusbarAuto(color);
|
||||
} else {
|
||||
statusBar.setBackgroundColor(ColorUtil.darkenColor(color));
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +47,6 @@ public abstract class AbsMainActivityFragment extends AbsMusicServiceFragment {
|
|||
public void setStatusbarColorAuto(View view) {
|
||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||
//noinspection ConstantConditions
|
||||
setStatusbarColor(view, ThemeStore.primaryColor(getContext()));
|
||||
setStatusbarColor(view, ColorUtil.darkenColor(ThemeStore.primaryColor(getContext())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import android.support.v4.app.Fragment;
|
|||
import android.view.View;
|
||||
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener;
|
||||
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,23 +34,20 @@ import code.name.monkey.retromusic.util.NavigationUtil;
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public abstract class AbsPlayerFragment extends AbsMusicServiceFragment implements
|
||||
Toolbar.OnMenuItemClickListener, PaletteColorHolder {
|
||||
|
||||
public abstract class AbsPlayerFragment extends AbsMusicServiceFragment implements Toolbar.OnMenuItemClickListener, PaletteColorHolder {
|
||||
public static final String TAG = AbsPlayerFragment.class.getSimpleName();
|
||||
private boolean isToolbarShown = true;
|
||||
private Callbacks callbacks;
|
||||
private AsyncTask updateIsFavoriteTask;
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
callbacks = (Callbacks) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new RuntimeException(
|
||||
context.getClass().getSimpleName() + " must implement " + Callbacks.class
|
||||
.getSimpleName());
|
||||
throw new RuntimeException(context.getClass().getSimpleName() + " must implement " + Callbacks.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistContract;
|
||||
|
@ -11,161 +14,160 @@ import code.name.monkey.retromusic.mvp.presenter.ArtistPresenter;
|
|||
import code.name.monkey.retromusic.ui.adapter.artist.ArtistAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ArtistsFragment extends
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> implements
|
||||
ArtistContract.ArtistView {
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> implements
|
||||
ArtistContract.ArtistView {
|
||||
|
||||
public static final String TAG = ArtistsFragment.class.getSimpleName();
|
||||
private ArtistPresenter presenter;
|
||||
public static final String TAG = ArtistsFragment.class.getSimpleName();
|
||||
private ArtistPresenter presenter;
|
||||
|
||||
public static ArtistsFragment newInstance() {
|
||||
public static ArtistsFragment newInstance() {
|
||||
|
||||
Bundle args = new Bundle();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
ArtistsFragment fragment = new ArtistsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new ArtistPresenter(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected ArtistAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
if (itemLayoutRes != R.layout.item_list) {
|
||||
itemLayoutRes = PreferenceUtil.getInstance(getContext()).getArtistGridStyle(getContext());
|
||||
ArtistsFragment fragment = new ArtistsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
ArrayList<Artist> dataSet =
|
||||
getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
|
||||
return new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
loadUsePalette(), getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_artists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSize(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).artistColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.artists);
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new ArtistPresenter(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.artists);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.unsubscribe();
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected ArtistAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
if (itemLayoutRes != R.layout.item_list) {
|
||||
itemLayoutRes = PreferenceUtil.getInstance(getContext()).getArtistGridStyle(getContext());
|
||||
}
|
||||
ArrayList<Artist> dataSet =
|
||||
getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
|
||||
return new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
loadUsePalette(), getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_artists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<>());
|
||||
}
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSize(getActivity());
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Artist> artists) {
|
||||
getAdapter().swapDataSet(artists);
|
||||
}
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).artistColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.artists);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.artists);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Artist> artists) {
|
||||
getAdapter().swapDataSet(artists);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import android.support.annotation.Nullable;
|
|||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreContract;
|
||||
|
@ -13,100 +16,95 @@ import code.name.monkey.retromusic.mvp.presenter.GenrePresenter;
|
|||
import code.name.monkey.retromusic.ui.adapter.GenreAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GenreFragment extends
|
||||
AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager> implements
|
||||
GenreContract.GenreView {
|
||||
AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager> implements
|
||||
GenreContract.GenreView {
|
||||
|
||||
private GenrePresenter mPresenter;
|
||||
private GenrePresenter mPresenter;
|
||||
|
||||
public static GenreFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
GenreFragment fragment = new GenreFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
mPresenter = new GenrePresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.genres);
|
||||
public static GenreFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
GenreFragment fragment = new GenreFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
mPresenter.subscribe();
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
mPresenter = new GenrePresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
mPresenter.subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mPresenter.unsubscribe();
|
||||
}
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected LinearLayoutManager createLayoutManager() {
|
||||
return new LinearLayoutManager(getActivity());
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected LinearLayoutManager createLayoutManager() {
|
||||
return new LinearLayoutManager(getActivity());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GenreAdapter createAdapter() {
|
||||
ArrayList<Genre> dataSet =
|
||||
getAdapter() == null ? new ArrayList<Genre>() : getAdapter().getDataSet();
|
||||
return new GenreAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list);
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected GenreAdapter createAdapter() {
|
||||
ArrayList<Genre> dataSet = getAdapter() == null ? new ArrayList<Genre>() : getAdapter().getDataSet();
|
||||
return new GenreAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Genre> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
@Override
|
||||
public void showData(ArrayList<Genre> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Genre>());
|
||||
}
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Genre>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
menu.removeItem(R.id.action_sort_order);
|
||||
menu.removeItem(R.id.action_grid_size);
|
||||
menu.removeItem(R.id.action_new_playlist);
|
||||
}
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
menu.removeItem(R.id.action_sort_order);
|
||||
menu.removeItem(R.id.action_grid_size);
|
||||
menu.removeItem(R.id.action_new_playlist);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_genres;
|
||||
}
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_genres;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.BottomNavigationView;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
@ -18,10 +21,12 @@ import android.view.MenuItem;
|
|||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
|
||||
import butterknife.BindDrawable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
@ -29,6 +34,9 @@ import butterknife.Unbinder;
|
|||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.NavigationViewUtil;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
@ -39,13 +47,15 @@ import code.name.monkey.retromusic.helper.SortOrder;
|
|||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.misc.NavigationIconClickListener;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.IconImageView;
|
||||
|
||||
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder,
|
||||
MainActivityFragmentCallbacks {
|
||||
|
@ -62,9 +72,24 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.search)
|
||||
IconImageView search;
|
||||
@BindView(R.id.action_library)
|
||||
TextView actionLibrary;
|
||||
|
||||
@BindView(R.id.bottom_navigation)
|
||||
BottomNavigationView bottomNavigationView;
|
||||
|
||||
@BindView(R.id.fragment_container)
|
||||
View contentContainer;
|
||||
|
||||
@BindView(R.id.coordinator_layout)
|
||||
View coordinatorLayout;
|
||||
|
||||
@BindView(R.id.menu_container)
|
||||
View menuContainer;
|
||||
@BindDrawable(R.drawable.ic_menu_white_24dp)
|
||||
Drawable menu;
|
||||
@BindDrawable(R.drawable.ic_close_white_24dp)
|
||||
Drawable close;
|
||||
private Unbinder unBinder;
|
||||
private MaterialCab cab;
|
||||
private FragmentManager fragmentManager;
|
||||
|
@ -77,6 +102,28 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
return fragment;
|
||||
}
|
||||
|
||||
public static Fragment newInstance() {
|
||||
return new LibraryFragment();
|
||||
}
|
||||
|
||||
private void setupBottomView() {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
bottomNavigationView.setSelectedItemId(PreferenceUtil.getInstance(context).getLastPage());
|
||||
bottomNavigationView.setBackgroundColor(ThemeStore.primaryColor(context));
|
||||
bottomNavigationView.setOnNavigationItemSelectedListener(this::onOptionsItemSelected);
|
||||
int iconColor = ATHUtil.resolveColor(context, R.attr.iconColor);
|
||||
int accentColor = ThemeStore.accentColor(context);
|
||||
NavigationViewUtil.setItemIconColors(bottomNavigationView, iconColor, accentColor);
|
||||
NavigationViewUtil.setItemTextColors(bottomNavigationView, iconColor, accentColor);
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).tabTitles()) {
|
||||
bottomNavigationView.setItemTextAppearanceActive(R.style.HideTabTitleTextAppearance);
|
||||
bottomNavigationView.setItemTextAppearanceInactive(R.style.HideTabTitleTextAppearance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(@StringRes int name) {
|
||||
title.setText(getString(name));
|
||||
}
|
||||
|
@ -108,45 +155,43 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setStatusbarColorAuto(view);
|
||||
getMainActivity().setBottomBarVisibility(View.VISIBLE);
|
||||
setupBottomView();
|
||||
setupToolbar();
|
||||
inflateFragment();
|
||||
}
|
||||
|
||||
private void inflateFragment() {
|
||||
if (getArguments() == null) {
|
||||
if (savedInstanceState == null) {
|
||||
selectedFragment(SongsFragment.newInstance());
|
||||
return;
|
||||
}
|
||||
switch (getArguments().getInt(CURRENT_TAB_ID)) {
|
||||
default:
|
||||
case R.id.action_song:
|
||||
selectedFragment(SongsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_album:
|
||||
selectedFragment(AlbumsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_artist:
|
||||
selectedFragment(ArtistsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_playlist:
|
||||
selectedFragment(PlaylistsFragment.newInstance());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void setupToolbar() {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
TintHelper.setTintAuto(search, ThemeStore.textColorSecondary(getContext()), false);
|
||||
actionLibrary.setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)));
|
||||
actionLibrary.setBackgroundResource(R.drawable.et_bg_circular_top_corners);
|
||||
TintHelper.setTintAuto(actionLibrary, ThemeStore.accentColor(getContext()), true);
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
int darkPrimaryColor = ColorUtil.darkenColor(primaryColor);
|
||||
|
||||
TintHelper.setTintAuto(contentContainer, primaryColor, true);
|
||||
|
||||
toolbar.setBackgroundColor(darkPrimaryColor);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
|
||||
appbar.setBackgroundColor(darkPrimaryColor);
|
||||
appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) ->
|
||||
getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
|
||||
getMainActivity().setTitle(null);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
|
||||
getContext(),
|
||||
contentContainer,
|
||||
menuContainer,
|
||||
new AccelerateDecelerateInterpolator(),
|
||||
menu,
|
||||
close
|
||||
));
|
||||
coordinatorLayout.setBackgroundColor(ColorUtil.darkenColor(primaryColor));
|
||||
}
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
|
@ -196,10 +241,6 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
return cab;
|
||||
}
|
||||
|
||||
@OnClick(R.id.search)
|
||||
void search() {
|
||||
NavigationUtil.goToSearch(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
|
@ -270,7 +311,8 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
}
|
||||
|
||||
private boolean handleSortOrderMenuItem(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) {
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment
|
||||
fragment, @NonNull MenuItem item) {
|
||||
String sortOrder = null;
|
||||
if (fragment instanceof AlbumsFragment) {
|
||||
switch (item.getItemId()) {
|
||||
|
@ -354,6 +396,21 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
}
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_song:
|
||||
selectedFragment(SongsFragment.newInstance());
|
||||
return true;
|
||||
case R.id.action_album:
|
||||
selectedFragment(AlbumsFragment.newInstance());
|
||||
return true;
|
||||
case R.id.action_artist:
|
||||
selectedFragment(ArtistsFragment.newInstance());
|
||||
return true;
|
||||
case R.id.action_playlist:
|
||||
selectedFragment(PlaylistsFragment.newInstance());
|
||||
return true;
|
||||
case R.id.action_genre:
|
||||
selectedFragment(GenreFragment.newInstance());
|
||||
return true;
|
||||
case R.id.action_new_playlist:
|
||||
CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST");
|
||||
return true;
|
||||
|
@ -432,7 +489,8 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
|
||||
|
||||
private boolean handleGridSizeMenuItem(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) {
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment
|
||||
fragment, @NonNull MenuItem item) {
|
||||
int gridSize = 0;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_grid_size_1:
|
||||
|
@ -468,4 +526,27 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_home, R.id.action_settings, R.id.action_folders})
|
||||
void startUserInfo(View view) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_settings:
|
||||
NavigationUtil.goToSettings(activity);
|
||||
break;
|
||||
case R.id.action_home:
|
||||
getMainActivity().setCurrentFragment(MainActivity.HOME);
|
||||
break;
|
||||
case R.id.action_folders:
|
||||
getMainActivity().setCurrentFragment(MainActivity.FOLDERS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addAppbarLayoutElevation(float v) {
|
||||
//TransitionManager.beginDelayedTransition(appbar);
|
||||
//appbar.setElevation(v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,14 +54,14 @@ public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<Playl
|
|||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
getLibraryFragment().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.SongContract;
|
||||
|
@ -12,164 +15,163 @@ import code.name.monkey.retromusic.ui.adapter.song.ShuffleButtonSongAdapter;
|
|||
import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class SongsFragment extends
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager> implements
|
||||
SongContract.SongView {
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager> implements
|
||||
SongContract.SongView {
|
||||
|
||||
private SongPresenter presenter;
|
||||
private SongPresenter presenter;
|
||||
|
||||
public SongsFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static SongsFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
SongsFragment fragment = new SongsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new SongPresenter(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_songs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected SongAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
boolean usePalette = loadUsePalette();
|
||||
ArrayList<Song> dataSet =
|
||||
getAdapter() == null ? new ArrayList<Song>() : getAdapter().getDataSet();
|
||||
|
||||
if (getGridSize() <= getMaxGridSizeForList()) {
|
||||
return new ShuffleButtonSongAdapter(getLibraryFragment().getMainActivity(), dataSet,
|
||||
itemLayoutRes, usePalette, getLibraryFragment());
|
||||
public SongsFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
return new SongAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
usePalette, getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSize(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).songColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.songs);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
public static SongsFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
SongsFragment fragment = new SongsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.songs);
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new SongPresenter(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
presenter.unsubscribe();
|
||||
super.onDestroy();
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_songs;
|
||||
}
|
||||
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected SongAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
boolean usePalette = loadUsePalette();
|
||||
ArrayList<Song> dataSet =
|
||||
getAdapter() == null ? new ArrayList<Song>() : getAdapter().getDataSet();
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Song> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
if (getGridSize() <= getMaxGridSizeForList()) {
|
||||
return new ShuffleButtonSongAdapter(getLibraryFragment().getMainActivity(), dataSet,
|
||||
itemLayoutRes, usePalette, getLibraryFragment());
|
||||
}
|
||||
return new SongAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
usePalette, getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Song>());
|
||||
}
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSize(getActivity());
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongSortOrder();
|
||||
}
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongSortOrder(sortOrder);
|
||||
}
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
@Override
|
||||
public void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).songColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.songs);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.songs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
presenter.unsubscribe();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Song> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Song>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity.folders;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
|
@ -22,6 +23,7 @@ import android.view.MenuInflater;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
@ -41,13 +43,16 @@ import java.util.Comparator;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindDrawable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
@ -58,12 +63,15 @@ import code.name.monkey.retromusic.interfaces.CabHolder;
|
|||
import code.name.monkey.retromusic.interfaces.LoaderIds;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||
import code.name.monkey.retromusic.misc.NavigationIconClickListener;
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.SongFileAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.util.FileUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
@ -85,7 +93,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
protected static final String CRUMBS = "crumbs";
|
||||
private static final int LOADER_ID = LoaderIds.FOLDERS_FRAGMENT;
|
||||
@BindView(R.id.coordinator_layout)
|
||||
CoordinatorLayout coordinatorLayout;
|
||||
View coordinatorLayout;
|
||||
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
|
@ -102,13 +110,25 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
@BindView(R.id.bread_crumbs)
|
||||
BreadCrumbLayout breadCrumbs;
|
||||
|
||||
@BindView(R.id.appbar)
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appbar;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
FastScrollRecyclerView recyclerView;
|
||||
|
||||
Comparator<File> fileComparator = (lhs, rhs) -> {
|
||||
@BindView(R.id.action_folders)
|
||||
TextView actionFolders;
|
||||
|
||||
@BindView(R.id.menu_container)
|
||||
View menuContainer;
|
||||
|
||||
@BindDrawable(R.drawable.ic_menu_white_24dp)
|
||||
Drawable menu;
|
||||
|
||||
@BindDrawable(R.drawable.ic_close_white_24dp)
|
||||
Drawable close;
|
||||
|
||||
private Comparator<File> fileComparator = (lhs, rhs) -> {
|
||||
if (lhs.isDirectory() && !rhs.isDirectory()) {
|
||||
return -1;
|
||||
} else if (!lhs.isDirectory() && rhs.isDirectory()) {
|
||||
|
@ -118,7 +138,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
(rhs.getName());
|
||||
}
|
||||
};
|
||||
|
||||
private Unbinder unbinder;
|
||||
private SongFileAdapter adapter;
|
||||
private MaterialCab cab;
|
||||
|
@ -138,7 +157,6 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
return frag;
|
||||
}
|
||||
|
||||
|
||||
public static File getDefaultStartDirectory() {
|
||||
File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
|
||||
File startFolder;
|
||||
|
@ -184,6 +202,25 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_library, R.id.action_settings, R.id.action_home})
|
||||
void startUserInfo(View view) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_home:
|
||||
getMainActivity().setCurrentFragment(MainActivity.HOME);
|
||||
break;
|
||||
case R.id.action_library:
|
||||
getMainActivity().setCurrentFragment(MainActivity.LIBRARY);
|
||||
break;
|
||||
case R.id.action_settings:
|
||||
NavigationUtil.goToSettings(activity);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BreadCrumbLayout.Crumb getActiveCrumb() {
|
||||
return breadCrumbs != null && breadCrumbs.size() > 0 ? breadCrumbs
|
||||
|
@ -221,10 +258,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
setStatusbarColorAuto(view);
|
||||
getMainActivity().getSlidingUpPanelLayout().setShadowHeight(0);
|
||||
getMainActivity().setBottomBarVisibility(View.GONE);
|
||||
|
||||
setUpAppbarColor();
|
||||
setUpToolbar();
|
||||
setUpBreadCrumbs();
|
||||
setUpRecyclerView();
|
||||
setUpAdapter();
|
||||
|
@ -232,26 +267,39 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
}
|
||||
|
||||
private void setUpAppbarColor() {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
actionFolders.setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)));
|
||||
actionFolders.setBackgroundResource(R.drawable.et_bg_circular_top_corners);
|
||||
TintHelper.setTintAuto(actionFolders, ThemeStore.accentColor(getContext()), true);
|
||||
|
||||
|
||||
//noinspection ConstantConditions
|
||||
int primaryColor = ThemeStore.primaryColor(getActivity());
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
int darkPrimaryColor = ColorUtil.darkenColor(primaryColor);
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
|
||||
//noinspection ConstantConditions
|
||||
getActivity().setTitle(null);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
|
||||
getContext(),
|
||||
container,
|
||||
menuContainer,
|
||||
new AccelerateDecelerateInterpolator(),
|
||||
menu,
|
||||
close
|
||||
));
|
||||
TintHelper.setTintAuto(container, primaryColor, true);
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
//breadCrumbs.setBackgroundColor(primaryColor);
|
||||
appbar.setBackgroundColor(darkPrimaryColor);
|
||||
toolbar.setBackgroundColor(darkPrimaryColor);
|
||||
coordinatorLayout.setBackgroundColor(darkPrimaryColor);
|
||||
|
||||
breadCrumbs.setActivatedContentColor(ToolbarContentTintHelper.toolbarTitleColor(getActivity(), ColorUtil.darkenColor(primaryColor)));
|
||||
breadCrumbs.setDeactivatedContentColor(ToolbarContentTintHelper.toolbarSubtitleColor(getActivity(), ColorUtil.darkenColor(primaryColor)));
|
||||
appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
//noinspection ConstantConditions
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
//noinspection ConstantConditions
|
||||
getActivity().setTitle(R.string.folders);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
private void setUpBreadCrumbs() {
|
||||
breadCrumbs.setCallback(this);
|
||||
}
|
||||
|
@ -387,7 +435,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
String.format(getString(R.string.not_listed_in_media_store), file1.getName())),
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.action_scan,
|
||||
v -> new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths))
|
||||
v -> new ListPathsAsyncTask(getActivity(), this::scanPaths)
|
||||
.execute(new ListPathsAsyncTask.LoadingInfo(finalFile, AUDIO_FILE_FILTER)))
|
||||
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
||||
.show();
|
||||
|
@ -441,7 +489,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_scan:
|
||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths))
|
||||
new ListPathsAsyncTask(getActivity(), this::scanPaths)
|
||||
.execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER));
|
||||
return true;
|
||||
}
|
||||
|
@ -468,7 +516,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
getFileComparator()));
|
||||
return true;
|
||||
case R.id.action_scan:
|
||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths))
|
||||
new ListPathsAsyncTask(getActivity(), this::scanPaths)
|
||||
.execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.fragments.mainactivity.home;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -16,6 +17,11 @@ import android.view.Display;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AnticipateInterpolator;
|
||||
import android.view.animation.AnticipateOvershootInterpolator;
|
||||
import android.view.animation.BounceInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
@ -23,18 +29,22 @@ import android.widget.TextView;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindDrawable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.HomeOptionDialog;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.misc.NavigationIconClickListener;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
|
@ -44,6 +54,7 @@ import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
|
|||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
|
||||
import code.name.monkey.retromusic.mvp.contract.HomeContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.HomePresenter;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.GenreAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumFullWithAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.artist.ArtistAdapter;
|
||||
|
@ -59,45 +70,70 @@ import io.reactivex.schedulers.Schedulers;
|
|||
|
||||
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
|
||||
|
||||
public class BannerHomeFragment extends AbsMainActivityFragment implements
|
||||
MainActivityFragmentCallbacks,
|
||||
HomeContract.HomeView {
|
||||
public class BannerHomeFragment extends AbsMainActivityFragment implements MainActivityFragmentCallbacks, HomeContract.HomeView {
|
||||
|
||||
private static final String TAG = "HomeFragment";
|
||||
Unbinder unbinder;
|
||||
@BindView(R.id.home_toolbar)
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout appbar;
|
||||
|
||||
@BindView(R.id.menu_container)
|
||||
View menuContainer;
|
||||
|
||||
@BindView(R.id.user_image)
|
||||
CircularImageView userImage;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recentArtistRV;
|
||||
|
||||
@BindView(R.id.recent_album)
|
||||
RecyclerView recentAlbumRV;
|
||||
|
||||
@BindView(R.id.top_artist)
|
||||
RecyclerView topArtistRV;
|
||||
|
||||
@BindView(R.id.top_album)
|
||||
MetalRecyclerViewPager topAlbumRV;
|
||||
|
||||
@BindView(R.id.recent_artist_container)
|
||||
View recentArtistContainer;
|
||||
|
||||
@BindView(R.id.recent_albums_container)
|
||||
View recentAlbumsContainer;
|
||||
|
||||
@BindView(R.id.top_artist_container)
|
||||
View topArtistContainer;
|
||||
|
||||
@BindView(R.id.top_albums_container)
|
||||
View topAlbumContainer;
|
||||
|
||||
@BindView(R.id.genres)
|
||||
RecyclerView genresRecyclerView;
|
||||
|
||||
@BindView(R.id.genre_container)
|
||||
LinearLayout genreContainer;
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
|
||||
@BindView(R.id.content_container)
|
||||
View contentContainer;
|
||||
|
||||
@BindView(R.id.coordinator_layout)
|
||||
View coordinatorLayout;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.search)
|
||||
ImageView search;
|
||||
|
||||
@BindView(R.id.action_home)
|
||||
TextView actionHome;
|
||||
|
||||
@BindDrawable(R.drawable.ic_menu_white_24dp)
|
||||
Drawable menu;
|
||||
|
||||
@BindDrawable(R.drawable.ic_close_white_24dp)
|
||||
Drawable close;
|
||||
|
||||
private HomePresenter homePresenter;
|
||||
private CompositeDisposable disposable;
|
||||
|
@ -109,7 +145,6 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
private void loadImageFromStorage(ImageView imageView) {
|
||||
//noinspection ConstantConditions
|
||||
disposable.add(new Compressor(getContext())
|
||||
|
@ -119,7 +154,7 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(
|
||||
new File(PreferenceUtil.getInstance(getContext()).getProfileImage(), USER_PROFILE))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(imageView::setImageBitmap,
|
||||
throwable -> imageView.setImageDrawable(ContextCompat
|
||||
|
@ -147,9 +182,7 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setStatusbarColorAuto(view);
|
||||
getMainActivity().getSlidingUpPanelLayout().setShadowHeight(8);
|
||||
getMainActivity().setBottomBarVisibility(View.VISIBLE);
|
||||
|
||||
setTextColor();
|
||||
setupToolbar();
|
||||
loadImageFromStorage(userImage);
|
||||
|
||||
|
@ -159,19 +192,34 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void setupToolbar() {
|
||||
//noinspection ConstantConditions
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
int darkPrimaryColor = ColorUtil.darkenColor(primaryColor);
|
||||
|
||||
toolbar.setBackgroundColor(darkPrimaryColor);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
|
||||
appbar.setBackgroundColor(darkPrimaryColor);
|
||||
appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) ->
|
||||
getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
|
||||
|
||||
getActivity().setTitle(R.string.app_name);
|
||||
getMainActivity().setTitle(null);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
|
||||
getContext(),
|
||||
contentContainer,
|
||||
menuContainer,
|
||||
new AccelerateDecelerateInterpolator(),
|
||||
menu,
|
||||
close
|
||||
));
|
||||
coordinatorLayout.setBackgroundColor(ColorUtil.darkenColor(primaryColor));
|
||||
TintHelper.setTintAuto(contentContainer, primaryColor, true);
|
||||
}
|
||||
|
||||
private void setTextColor() {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
TintHelper.setTintAuto(search, ThemeStore.textColorPrimary(getContext()), false);
|
||||
TintHelper.setTintAuto(container, primaryColor, true);
|
||||
actionHome.setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)));
|
||||
actionHome.setBackgroundResource(R.drawable.et_bg_circular_top_corners);
|
||||
TintHelper.setTintAuto(actionHome, accentColor, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -227,7 +275,7 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
|
||||
private void checkPadding() {
|
||||
int height = getResources().getDimensionPixelSize(R.dimen.mini_player_height);
|
||||
container.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0);
|
||||
contentContainer.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -293,15 +341,14 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
}
|
||||
|
||||
|
||||
@OnClick({R.id.last_added, R.id.top_played, R.id.action_shuffle, R.id.history,
|
||||
R.id.user_image, R.id.search})
|
||||
@OnClick({R.id.last_added, R.id.top_played, R.id.search, R.id.action_shuffle, R.id.history,
|
||||
R.id.user_image, R.id.action_library, R.id.action_settings, R.id.action_folders})
|
||||
void startUserInfo(View view) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_shuffle:
|
||||
MusicPlayerRemote
|
||||
.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true);
|
||||
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true);
|
||||
break;
|
||||
case R.id.last_added:
|
||||
NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity));
|
||||
|
@ -312,20 +359,22 @@ public class BannerHomeFragment extends AbsMainActivityFragment implements
|
|||
case R.id.history:
|
||||
NavigationUtil.goToPlaylistNew(activity, new HistoryPlaylist(activity));
|
||||
break;
|
||||
case R.id.search:
|
||||
NavigationUtil.goToSearch(activity);
|
||||
break;
|
||||
case R.id.user_image:
|
||||
new HomeOptionDialog().show(getFragmentManager(), TAG);
|
||||
break;
|
||||
case R.id.action_folders:
|
||||
getMainActivity().setCurrentFragment(MainActivity.FOLDERS);
|
||||
break;
|
||||
case R.id.action_library:
|
||||
getMainActivity().setCurrentFragment(MainActivity.LIBRARY);
|
||||
break;
|
||||
case R.id.action_settings:
|
||||
NavigationUtil.goToSettings(activity);
|
||||
break;
|
||||
case R.id.search:
|
||||
NavigationUtil.goToSearch(activity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
homePresenter.loadRecentArtists();
|
||||
homePresenter.loadRecentAlbums();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package code.name.monkey.retromusic.ui.fragments.mainactivity.home;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -17,6 +18,8 @@ import android.view.Display;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AnticipateOvershootInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
@ -29,6 +32,7 @@ import java.util.ArrayList;
|
|||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
|
||||
import butterknife.BindDrawable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
@ -42,6 +46,7 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
|||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.misc.NavigationIconClickListener;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
|
@ -75,41 +80,66 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
Unbinder unbinder;
|
||||
@BindView(R.id.home_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.appbar)
|
||||
|
||||
@BindView(R.id.menu_container)
|
||||
View menuContainer;
|
||||
|
||||
@BindView(R.id.coordinator_layout)
|
||||
View coordinatorLayout;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appbar;
|
||||
|
||||
@BindView(R.id.image)
|
||||
ImageView imageView;
|
||||
|
||||
@BindView(R.id.user_image)
|
||||
CircularImageView userImage;
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
CollapsingToolbarLayout toolbarLayout;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recentArtistRV;
|
||||
|
||||
@BindView(R.id.recent_album)
|
||||
RecyclerView recentAlbumRV;
|
||||
|
||||
@BindView(R.id.top_artist)
|
||||
RecyclerView topArtistRV;
|
||||
|
||||
@BindView(R.id.top_album)
|
||||
MetalRecyclerViewPager topAlbumRV;
|
||||
|
||||
@BindView(R.id.recent_artist_container)
|
||||
View recentArtistContainer;
|
||||
|
||||
@BindView(R.id.recent_albums_container)
|
||||
View recentAlbumsContainer;
|
||||
|
||||
@BindView(R.id.top_artist_container)
|
||||
View topArtistContainer;
|
||||
|
||||
@BindView(R.id.top_albums_container)
|
||||
View topAlbumContainer;
|
||||
|
||||
@BindView(R.id.genres)
|
||||
RecyclerView genresRecyclerView;
|
||||
|
||||
@BindView(R.id.genre_container)
|
||||
LinearLayout genreContainer;
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
|
||||
@BindView(R.id.content_container)
|
||||
View contentContainer;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.search)
|
||||
ImageView search;
|
||||
|
||||
@BindDrawable(R.drawable.ic_menu_white_24dp)
|
||||
Drawable menu;
|
||||
|
||||
@BindDrawable(R.drawable.ic_close_white_24dp)
|
||||
Drawable close;
|
||||
|
||||
private HomePresenter homePresenter;
|
||||
private CompositeDisposable disposable;
|
||||
|
@ -206,7 +236,6 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
getMainActivity().getSlidingUpPanelLayout().setShadowHeight(8);
|
||||
getMainActivity().setBottomBarVisibility(View.VISIBLE);
|
||||
|
||||
setupToolbar();
|
||||
loadImageFromStorage(userImage);
|
||||
|
@ -219,8 +248,7 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
@SuppressWarnings("ConstantConditions")
|
||||
private void setupToolbar() {
|
||||
if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar
|
||||
.getLayoutParams();
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
|
||||
params.topMargin = RetroUtil.getStatusBarHeight(getContext());
|
||||
toolbar.setLayoutParams(params);
|
||||
}
|
||||
|
@ -241,20 +269,27 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
color = ContextCompat.getColor(getContext(), R.color.md_white_1000);
|
||||
break;
|
||||
}
|
||||
TintHelper.setTintAuto(search, color, false);
|
||||
title.setTextColor(color);
|
||||
}
|
||||
});
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
|
||||
TintHelper.setTintAuto(container, primaryColor, true);
|
||||
TintHelper.setTintAuto(coordinatorLayout, primaryColor, true);
|
||||
toolbarLayout.setStatusBarScrimColor(primaryColor);
|
||||
toolbarLayout.setContentScrimColor(primaryColor);
|
||||
|
||||
toolbar.setTitle(R.string.home);
|
||||
getActivity().setTitle(null);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
|
||||
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
|
||||
getContext(),
|
||||
contentContainer,
|
||||
menuContainer,
|
||||
new AccelerateDecelerateInterpolator(),
|
||||
menu,
|
||||
close
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -310,7 +345,7 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
|
||||
private void checkPadding() {
|
||||
int height = getResources().getDimensionPixelSize(R.dimen.mini_player_height);
|
||||
container.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0);
|
||||
contentContainer.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -377,14 +412,13 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
|
||||
|
||||
@OnClick({R.id.last_added, R.id.top_played, R.id.action_shuffle, R.id.history,
|
||||
R.id.user_image, R.id.search})
|
||||
R.id.user_image})
|
||||
void startUserInfo(View view) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_shuffle:
|
||||
MusicPlayerRemote
|
||||
.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true);
|
||||
MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true);
|
||||
break;
|
||||
case R.id.last_added:
|
||||
NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity));
|
||||
|
@ -395,9 +429,7 @@ public class HomeFragment extends AbsMainActivityFragment implements MainActivit
|
|||
case R.id.history:
|
||||
NavigationUtil.goToPlaylistNew(activity, new HistoryPlaylist(activity));
|
||||
break;
|
||||
case R.id.search:
|
||||
NavigationUtil.goToSearch(activity);
|
||||
break;
|
||||
|
||||
case R.id.user_image:
|
||||
new HomeOptionDialog().show(getFragmentManager(), TAG);
|
||||
break;
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.support.v4.view.ViewPager;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -21,134 +22,134 @@ import code.name.monkey.retromusic.util.PreferenceUtil;
|
|||
|
||||
|
||||
public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
||||
ViewPager.OnPageChangeListener {
|
||||
ViewPager.OnPageChangeListener {
|
||||
|
||||
public static final String TAG = PlayerAlbumCoverFragment.class.getSimpleName();
|
||||
public static final long VISIBILITY_ANIM_DURATION = 300;
|
||||
@BindView(R.id.player_album_cover_viewpager)
|
||||
ViewPager viewPager;
|
||||
private Unbinder unbinder;
|
||||
private Callbacks callbacks;
|
||||
private int currentPosition;
|
||||
private AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver colorReceiver =
|
||||
new AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver() {
|
||||
@Override
|
||||
public void onColorReady(int color, int requestCode) {
|
||||
if (currentPosition == requestCode) {
|
||||
notifyColorChange(color);
|
||||
}
|
||||
public static final String TAG = PlayerAlbumCoverFragment.class.getSimpleName();
|
||||
public static final long VISIBILITY_ANIM_DURATION = 300;
|
||||
@BindView(R.id.player_album_cover_viewpager)
|
||||
ViewPager viewPager;
|
||||
private Unbinder unbinder;
|
||||
private Callbacks callbacks;
|
||||
private int currentPosition;
|
||||
private AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver colorReceiver =
|
||||
new AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver() {
|
||||
@Override
|
||||
public void onColorReady(int color, int requestCode) {
|
||||
if (currentPosition == requestCode) {
|
||||
notifyColorChange(color);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void removeSlideEffect() {
|
||||
ParallaxPagerTransformer transformer = new ParallaxPagerTransformer(R.id.player_image);
|
||||
transformer.setSpeed(0.3f);
|
||||
viewPager.setPageTransformer(true, transformer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_player_album_cover, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (PreferenceUtil.getInstance(getContext()).carouselEffect() && !(
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen() == NowPlayingScreen.FULL) ||
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen()
|
||||
== NowPlayingScreen.FLAT))) {
|
||||
viewPager.setClipToPadding(false);
|
||||
viewPager.setPadding(96, 0, 96, 0);
|
||||
viewPager.setPageMargin(18);
|
||||
|
||||
viewPager.setPageTransformer(false, new CustPagerTransformer(getContext()));
|
||||
} else {
|
||||
viewPager.setPageTransformer(true, new NormalPageTransformer());
|
||||
}
|
||||
};
|
||||
|
||||
public void removeSlideEffect() {
|
||||
ParallaxPagerTransformer transformer = new ParallaxPagerTransformer(R.id.player_image);
|
||||
transformer.setSpeed(0.3f);
|
||||
viewPager.setPageTransformer(true, transformer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_player_album_cover, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (PreferenceUtil.getInstance(getContext()).carouselEffect() && !(
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen() == NowPlayingScreen.FULL) ||
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen()
|
||||
== NowPlayingScreen.FLAT))) {
|
||||
viewPager.setClipToPadding(false);
|
||||
viewPager.setPadding(96, 0, 96, 0);
|
||||
viewPager.setPageMargin(18);
|
||||
|
||||
viewPager.setPageTransformer(false, new CustPagerTransformer(getContext()));
|
||||
} else {
|
||||
viewPager.setPageTransformer(true, new NormalPageTransformer());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
viewPager.removeOnPageChangeListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
|
||||
private void updatePlayingQueue() {
|
||||
viewPager.setAdapter(
|
||||
new AlbumCoverPagerAdapter(getFragmentManager(), MusicPlayerRemote.getPlayingQueue()));
|
||||
//noinspection ConstantConditions
|
||||
viewPager.getAdapter().notifyDataSetChanged();
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
onPageSelected(MusicPlayerRemote.getPosition());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
currentPosition = position;
|
||||
if (viewPager.getAdapter() != null) {
|
||||
((AlbumCoverPagerAdapter) viewPager.getAdapter()).receiveColor(colorReceiver, position);
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
viewPager.removeOnPageChangeListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
if (position != MusicPlayerRemote.getPosition()) {
|
||||
MusicPlayerRemote.playSongAt(position);
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void notifyColorChange(int color) {
|
||||
if (callbacks != null) {
|
||||
callbacks.onColorChanged(color);
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallbacks(Callbacks listener) {
|
||||
callbacks = listener;
|
||||
}
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
|
||||
public void removeEffect() {
|
||||
viewPager.setPageTransformer(false, null);
|
||||
}
|
||||
private void updatePlayingQueue() {
|
||||
viewPager.setAdapter(
|
||||
new AlbumCoverPagerAdapter(getFragmentManager(), MusicPlayerRemote.getPlayingQueue()));
|
||||
//noinspection ConstantConditions
|
||||
viewPager.getAdapter().notifyDataSetChanged();
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
onPageSelected(MusicPlayerRemote.getPosition());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
currentPosition = position;
|
||||
if (viewPager.getAdapter() != null) {
|
||||
((AlbumCoverPagerAdapter) viewPager.getAdapter()).receiveColor(colorReceiver, position);
|
||||
}
|
||||
if (position != MusicPlayerRemote.getPosition()) {
|
||||
MusicPlayerRemote.playSongAt(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public interface Callbacks {
|
||||
private void notifyColorChange(int color) {
|
||||
if (callbacks != null) {
|
||||
callbacks.onColorChanged(color);
|
||||
}
|
||||
}
|
||||
|
||||
void onColorChanged(int color);
|
||||
public void setCallbacks(Callbacks listener) {
|
||||
callbacks = listener;
|
||||
}
|
||||
|
||||
void onFavoriteToggled();
|
||||
public void removeEffect() {
|
||||
viewPager.setPageTransformer(false, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
|
||||
void onColorChanged(int color);
|
||||
|
||||
void onFavoriteToggled();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,13 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -31,287 +38,282 @@ import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
|
|||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class BlurPlayerFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.toolbar_container)
|
||||
View toolbarContainer;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@Nullable
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@Nullable
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.toolbar_container)
|
||||
View toolbarContainer;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@Nullable
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@Nullable
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
private int lastColor;
|
||||
private BlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
private int lastColor;
|
||||
private BlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
private RecyclerView.Adapter wrappedAdapter;
|
||||
private RecyclerViewDragDropManager recyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter playingQueueAdapter;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private RecyclerView.Adapter wrappedAdapter;
|
||||
private RecyclerViewDragDropManager recyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter playingQueueAdapter;
|
||||
private LinearLayoutManager layoutManager;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
|
||||
if (title != null && playingQueueAdapter != null) {
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
title.setTextColor(Color.BLACK);
|
||||
playingQueueAdapter.usePalette(false);
|
||||
} else {
|
||||
title.setTextColor(Color.WHITE);
|
||||
playingQueueAdapter.usePalette(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.release();
|
||||
recyclerViewDragDropManager = null;
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setItemAnimator(null);
|
||||
recyclerView.setAdapter(null);
|
||||
recyclerView = null;
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
if (wrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter);
|
||||
wrappedAdapter = null;
|
||||
}
|
||||
playingQueueAdapter = null;
|
||||
layoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_blur, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (BlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
//noinspection ConstantConditions
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("new_blur_amount", 25);
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.override(320, 480)
|
||||
.transform(new BlurTransformation.Builder(getActivity()).blurRadius(blurAmount).build())
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
|
||||
if (title != null && playingQueueAdapter != null) {
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
title.setTextColor(Color.BLACK);
|
||||
playingQueueAdapter.usePalette(false);
|
||||
} else {
|
||||
title.setTextColor(Color.WHITE);
|
||||
playingQueueAdapter.usePalette(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
updateQueuePosition();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView != null) {
|
||||
recyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
playingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_song,
|
||||
false,
|
||||
null);
|
||||
wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(playingQueueAdapter);
|
||||
|
||||
layoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(wrappedAdapter);
|
||||
recyclerView.setItemAnimator(animator);
|
||||
recyclerViewDragDropManager.attachRecyclerView(recyclerView);
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter
|
||||
.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
if (recyclerView != null) {
|
||||
recyclerView.stopScroll();
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.cancelDrag();
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.release();
|
||||
recyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setItemAnimator(null);
|
||||
recyclerView.setAdapter(null);
|
||||
recyclerView = null;
|
||||
}
|
||||
|
||||
if (wrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter);
|
||||
wrappedAdapter = null;
|
||||
}
|
||||
playingQueueAdapter = null;
|
||||
layoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_blur, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (BlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
//noinspection ConstantConditions
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("new_blur_amount", 25);
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.override(320, 480)
|
||||
.transform(new BlurTransformation.Builder(getActivity()).blurRadius(blurAmount).build())
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
updateQueuePosition();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView != null) {
|
||||
recyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
playingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_song,
|
||||
false,
|
||||
null);
|
||||
wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(playingQueueAdapter);
|
||||
|
||||
layoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(wrappedAdapter);
|
||||
recyclerView.setItemAnimator(animator);
|
||||
recyclerViewDragDropManager.attachRecyclerView(recyclerView);
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter
|
||||
.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
if (recyclerView != null) {
|
||||
recyclerView.stopScroll();
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -25,167 +28,166 @@ import code.name.monkey.retromusic.model.Song;
|
|||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
public class CardBlurFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
|
||||
private int lastColor;
|
||||
private CardBlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
private int lastColor;
|
||||
private CardBlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_blur_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (CardBlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeEffect();
|
||||
}
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_blur_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (CardBlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeEffect();
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
/* for (int i = 0; i < toolbar.getMenu().size(); i++) {
|
||||
MenuItem menuItem = toolbar.getMenu().getItem(i);
|
||||
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
}*/
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("new_blur_amount", 25);
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.transform(new BlurTransformation.Builder(getActivity()).blurRadius(blurAmount).build())
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getInt("new_blur_amount", 25);
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.transform(new BlurTransformation.Builder(getActivity()).blurRadius(blurAmount).build())
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package code.name.monkey.retromusic.ui.fragments.player.flat;
|
|||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
@ -28,147 +29,147 @@ import code.name.monkey.retromusic.util.ViewUtil;
|
|||
import code.name.monkey.retromusic.views.DrawableGradient;
|
||||
|
||||
public class FlatPlayerFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.gradient_background)
|
||||
View colorBackground;
|
||||
@BindView(R.id.toolbar_container)
|
||||
FrameLayout toolbarContainer;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.gradient_background)
|
||||
View colorBackground;
|
||||
@BindView(R.id.toolbar_container)
|
||||
FrameLayout toolbarContainer;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private ValueAnimator valueAnimator;
|
||||
private FlatPlaybackControlsFragment flatPlaybackControlsFragment;
|
||||
private int lastColor;
|
||||
private Unbinder unbinder;
|
||||
private ValueAnimator valueAnimator;
|
||||
private FlatPlaybackControlsFragment flatPlaybackControlsFragment;
|
||||
private int lastColor;
|
||||
|
||||
private void setUpSubFragments() {
|
||||
flatPlaybackControlsFragment = (FlatPlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
private void setUpSubFragments() {
|
||||
flatPlaybackControlsFragment = (FlatPlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, ATHUtil.resolveColor(getContext(),
|
||||
R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
private void colorize(int i) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), android.R.color.transparent, i);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
GradientDrawable drawable = new DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{(int) animation.getAnimatedValue(), android.R.color.transparent}, 0);
|
||||
if (colorBackground != null) {
|
||||
colorBackground.setBackground(drawable);
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME).start();
|
||||
}
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_flat_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpPlayerToolbar();
|
||||
setUpSubFragments();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
flatPlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
flatPlaybackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
boolean isLight = ColorUtil.isColorLight(lastColor);
|
||||
return PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = color;
|
||||
flatPlaybackControlsFragment.setDark(color);
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
boolean isLight = ColorUtil.isColorLight(color);
|
||||
|
||||
//TransitionManager.beginDelayedTransition(mToolbar);
|
||||
int iconColor = PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, iconColor, getActivity());
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
colorize(color);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, ATHUtil.resolveColor(getContext(),
|
||||
R.attr.iconColor), getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
private void colorize(int i) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), android.R.color.transparent, i);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
GradientDrawable drawable = new DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{(int) animation.getAnimatedValue(), android.R.color.transparent}, 0);
|
||||
if (colorBackground != null) {
|
||||
colorBackground.setBackground(drawable);
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME).start();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_flat_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpPlayerToolbar();
|
||||
setUpSubFragments();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
flatPlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
flatPlaybackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
boolean isLight = ColorUtil.isColorLight(lastColor);
|
||||
return PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = color;
|
||||
flatPlaybackControlsFragment.setDark(color);
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
boolean isLight = ColorUtil.isColorLight(color);
|
||||
|
||||
//TransitionManager.beginDelayedTransition(mToolbar);
|
||||
int iconColor = PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, iconColor, getActivity());
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
colorize(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,13 +9,11 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
|
|
|
@ -79,7 +79,7 @@ public class MaterialControlsFragment extends AbsPlayerControlsFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
@ -155,9 +155,14 @@ public class MaterialControlsFragment extends AbsPlayerControlsFragment {
|
|||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
updatePlayPauseColor();
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
lastPlaybackControlsColor = dark;
|
||||
}
|
||||
|
||||
updatePlayPauseColor();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.view.animation.AccelerateInterpolator;
|
|||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
@ -36,287 +37,287 @@ import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
|||
|
||||
public class SimplePlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_simple_controls_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
volumeContainer.setVisibility(
|
||||
PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
songCurrentProgress
|
||||
.setText(String.format("%s / %s", MusicUtil.getReadableDurationString(progress),
|
||||
MusicUtil.getReadableDurationString(total)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
TintHelper.setTintAuto(playPauseFab,
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)),
|
||||
false);
|
||||
TintHelper.setTintAuto(playPauseFab, dark, true);
|
||||
text.setTextColor(dark);
|
||||
} else {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
text.setTextColor(accentColor);
|
||||
TintHelper.setTintAuto(playPauseFab,
|
||||
MaterialValueHelper
|
||||
.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)),
|
||||
false);
|
||||
TintHelper.setTintAuto(playPauseFab, accentColor, true);
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
playPauseFab.setImageDrawable(
|
||||
playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_simple_controls_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
volumeContainer.setVisibility(
|
||||
PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
songCurrentProgress
|
||||
.setText(String.format("%s / %s", MusicUtil.getReadableDurationString(progress),
|
||||
MusicUtil.getReadableDurationString(total)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
TintHelper.setTintAuto(playPauseFab,
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)),
|
||||
false);
|
||||
TintHelper.setTintAuto(playPauseFab, dark, true);
|
||||
text.setTextColor(dark);
|
||||
} else {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
text.setTextColor(accentColor);
|
||||
TintHelper.setTintAuto(playPauseFab,
|
||||
MaterialValueHelper
|
||||
.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)),
|
||||
false);
|
||||
TintHelper.setTintAuto(playPauseFab, accentColor, true);
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(
|
||||
playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.support.v4.app.DialogFragment;
|
|||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -19,8 +18,6 @@ import code.name.monkey.retromusic.preferences.BlacklistPreference;
|
|||
import code.name.monkey.retromusic.preferences.BlacklistPreferenceDialog;
|
||||
import code.name.monkey.retromusic.preferences.NowPlayingScreenPreference;
|
||||
import code.name.monkey.retromusic.preferences.NowPlayingScreenPreferenceDialog;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.util.DensityUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
/**
|
||||
|
@ -56,22 +53,11 @@ public abstract class AbsSettingsFragment extends ATEPreferenceFragmentCompat {
|
|||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setDividerHeight(0);
|
||||
setDivider(new ColorDrawable(Color.TRANSPARENT));
|
||||
|
||||
//noinspection ConstantConditions
|
||||
getListView().setPadding(DensityUtil.dip2px(getContext(), 0), 0, 0, 0);
|
||||
getListView().addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
if (getActivity() != null) {
|
||||
((SettingsActivity) getActivity()).addAppbarLayoutElevation(recyclerView.canScrollVertically(RecyclerView.NO_POSITION) ? 8f : 0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
getListView().setBackgroundColor(ThemeStore.primaryColor(getContext()));
|
||||
getListView().setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
getListView().setPadding(0, 0, 0, 0);
|
||||
getListView().setPaddingRelative(0, 0, 0, 0);
|
||||
invalidateSettings();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
@ -14,79 +15,79 @@ import code.name.monkey.retromusic.util.PreferenceUtil;
|
|||
*/
|
||||
|
||||
public class NowPlayingSettingsFragment extends AbsSettingsFragment implements
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
updateNowPlayingScreenSummary();
|
||||
|
||||
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
|
||||
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
|
||||
return false;
|
||||
}
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference(
|
||||
"carousel_effect");
|
||||
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(
|
||||
getActivity().getString(R.string.pref_title_toggle_carousel_effect));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
final TwoStatePreference toggleFullScreen = (TwoStatePreference) findPreference(
|
||||
"toggle_full_screen");
|
||||
toggleFullScreen.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_now_playing_screen);
|
||||
addPreferencesFromResource(R.xml.pref_ui);
|
||||
addPreferencesFromResource(R.xml.pref_window);
|
||||
addPreferencesFromResource(R.xml.pref_lockscreen);
|
||||
}
|
||||
|
||||
private void updateNowPlayingScreenSummary() {
|
||||
//noinspection ConstantConditions
|
||||
findPreference("now_playing_screen_id")
|
||||
.setSummary(PreferenceUtil.getInstance(getActivity()).getNowPlayingScreen().titleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).unregisterOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch (key) {
|
||||
case PreferenceUtil.NOW_PLAYING_SCREEN_ID:
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
updateNowPlayingScreenSummary();
|
||||
break;
|
||||
case PreferenceUtil.CIRCULAR_ALBUM_ART:
|
||||
case PreferenceUtil.CAROUSEL_EFFECT:
|
||||
invalidateSettings();
|
||||
break;
|
||||
|
||||
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
|
||||
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
|
||||
return false;
|
||||
}
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference(
|
||||
"carousel_effect");
|
||||
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(
|
||||
getActivity().getString(R.string.pref_title_toggle_carousel_effect));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
final TwoStatePreference toggleFullScreen = (TwoStatePreference) findPreference(
|
||||
"toggle_full_screen");
|
||||
toggleFullScreen.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_now_playing_screen);
|
||||
addPreferencesFromResource(R.xml.pref_ui);
|
||||
addPreferencesFromResource(R.xml.pref_window);
|
||||
addPreferencesFromResource(R.xml.pref_lockscreen);
|
||||
}
|
||||
|
||||
private void updateNowPlayingScreenSummary() {
|
||||
//noinspection ConstantConditions
|
||||
findPreference("now_playing_screen_id")
|
||||
.setSummary(PreferenceUtil.getInstance(getActivity()).getNowPlayingScreen().titleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).unregisterOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch (key) {
|
||||
case PreferenceUtil.NOW_PLAYING_SCREEN_ID:
|
||||
updateNowPlayingScreenSummary();
|
||||
break;
|
||||
case PreferenceUtil.CIRCULAR_ALBUM_ART:
|
||||
case PreferenceUtil.CAROUSEL_EFFECT:
|
||||
invalidateSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.LayoutAnimationController;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
|
@ -11,13 +12,13 @@ import code.name.monkey.retromusic.R;
|
|||
*/
|
||||
public class AnimationUtil {
|
||||
|
||||
public static void runLayoutAnimation(final RecyclerView recyclerView) {
|
||||
final Context context = recyclerView.getContext();
|
||||
final LayoutAnimationController controller =
|
||||
AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_slide_from_bottom);
|
||||
public static void runLayoutAnimation(final RecyclerView recyclerView) {
|
||||
final Context context = recyclerView.getContext();
|
||||
final LayoutAnimationController controller =
|
||||
AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_slide_from_bottom);
|
||||
|
||||
recyclerView.setLayoutAnimation(controller);
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
recyclerView.scheduleLayoutAnimation();
|
||||
}
|
||||
recyclerView.setLayoutAnimation(controller);
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
recyclerView.scheduleLayoutAnimation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class DensityUtil {
|
|||
* Converts sp to px
|
||||
*
|
||||
* @param context Context
|
||||
* @param sp the value in sp
|
||||
* @param sp the value in sp
|
||||
* @return int
|
||||
*/
|
||||
public static int dip2sp(Context context, float sp) {
|
||||
|
|
|
@ -7,10 +7,7 @@ import android.provider.MediaStore;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.loaders.SortedCursor;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import io.reactivex.Observable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -25,227 +22,232 @@ import java.util.Collections;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.loaders.SortedCursor;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import io.reactivex.Observable;
|
||||
|
||||
|
||||
public final class FileUtil {
|
||||
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
public static byte[] readBytes(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = stream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
stream.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Observable<ArrayList<Song>> matchFilesWithMediaStore(@NonNull Context context,
|
||||
@Nullable List<File> files) {
|
||||
return SongLoader.getSongs(makeSongCursor(context, files));
|
||||
}
|
||||
|
||||
public static String safeGetCanonicalPath(File file) {
|
||||
try {
|
||||
return file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SortedCursor makeSongCursor(@NonNull final Context context,
|
||||
@Nullable final List<File> files) {
|
||||
String selection = null;
|
||||
String[] paths = null;
|
||||
|
||||
if (files != null) {
|
||||
paths = toPathArray(files);
|
||||
|
||||
if (files.size() > 0
|
||||
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
|
||||
selection =
|
||||
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
|
||||
}
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
Cursor songCursor = SongLoader
|
||||
.makeSongCursor(context, selection, selection == null ? null : paths);
|
||||
|
||||
return songCursor == null ? null
|
||||
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
|
||||
}
|
||||
|
||||
private static String makePlaceholders(int len) {
|
||||
StringBuilder sb = new StringBuilder(len * 2 - 1);
|
||||
sb.append("?");
|
||||
for (int i = 1; i < len; i++) {
|
||||
sb.append(",?");
|
||||
public static byte[] readBytes(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = stream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
stream.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String[] toPathArray(@Nullable List<File> files) {
|
||||
if (files != null) {
|
||||
String[] paths = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
@NonNull
|
||||
public static Observable<ArrayList<Song>> matchFilesWithMediaStore(@NonNull Context context,
|
||||
@Nullable List<File> files) {
|
||||
return SongLoader.getSongs(makeSongCursor(context, files));
|
||||
}
|
||||
|
||||
public static String safeGetCanonicalPath(File file) {
|
||||
try {
|
||||
return file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SortedCursor makeSongCursor(@NonNull final Context context,
|
||||
@Nullable final List<File> files) {
|
||||
String selection = null;
|
||||
String[] paths = null;
|
||||
|
||||
if (files != null) {
|
||||
paths = toPathArray(files);
|
||||
|
||||
if (files.size() > 0
|
||||
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
|
||||
selection =
|
||||
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
Cursor songCursor = SongLoader
|
||||
.makeSongCursor(context, selection, selection == null ? null : paths);
|
||||
|
||||
return songCursor == null ? null
|
||||
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
|
||||
}
|
||||
|
||||
private static String makePlaceholders(int len) {
|
||||
StringBuilder sb = new StringBuilder(len * 2 - 1);
|
||||
sb.append("?");
|
||||
for (int i = 1; i < len; i++) {
|
||||
sb.append(",?");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String[] toPathArray(@Nullable List<File> files) {
|
||||
if (files != null) {
|
||||
String[] paths = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
/*try {
|
||||
paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
paths[i] = files.get(i).getPath();
|
||||
}*/
|
||||
paths[i] = safeGetCanonicalPath(files.get(i));
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> fileList = new LinkedList<>();
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
if (found != null) {
|
||||
Collections.addAll(fileList, found);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> files = new LinkedList<>();
|
||||
internalListFilesDeep(files, directory, fileFilter);
|
||||
return files;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull Collection<File> files,
|
||||
@Nullable FileFilter fileFilter) {
|
||||
List<File> resFiles = new LinkedList<>();
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(resFiles, file, fileFilter);
|
||||
} else if (fileFilter == null || fileFilter.accept(file)) {
|
||||
resFiles.add(file);
|
||||
}
|
||||
}
|
||||
return resFiles;
|
||||
}
|
||||
|
||||
private static void internalListFilesDeep(@NonNull Collection<File> files,
|
||||
@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
|
||||
if (found != null) {
|
||||
for (File file : found) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(files, file, fileFilter);
|
||||
} else {
|
||||
files.add(file);
|
||||
paths[i] = safeGetCanonicalPath(files.get(i));
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) {
|
||||
if (mimeType == null || mimeType.equals("*/*")) {
|
||||
return true;
|
||||
} else {
|
||||
// get the file mime type
|
||||
String filename = file.toURI().toString();
|
||||
int dotPos = filename.lastIndexOf('.');
|
||||
if (dotPos == -1) {
|
||||
return false;
|
||||
}
|
||||
String fileExtension = filename.substring(dotPos + 1).toLowerCase();
|
||||
String fileType = mimeTypeMap.getMimeTypeFromExtension(fileExtension);
|
||||
if (fileType == null) {
|
||||
return false;
|
||||
}
|
||||
// check the 'type/subtype' pattern
|
||||
if (fileType.equals(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
// check the 'type/*' pattern
|
||||
int mimeTypeDelimiter = mimeType.lastIndexOf('/');
|
||||
if (mimeTypeDelimiter == -1) {
|
||||
return false;
|
||||
}
|
||||
String mimeTypeMainType = mimeType.substring(0, mimeTypeDelimiter);
|
||||
String mimeTypeSubtype = mimeType.substring(mimeTypeDelimiter + 1);
|
||||
if (!mimeTypeSubtype.equals("*")) {
|
||||
return false;
|
||||
}
|
||||
int fileTypeDelimiter = fileType.lastIndexOf('/');
|
||||
if (fileTypeDelimiter == -1) {
|
||||
return false;
|
||||
}
|
||||
String fileTypeMainType = fileType.substring(0, fileTypeDelimiter);
|
||||
if (fileTypeMainType.equals(mimeTypeMainType)) {
|
||||
return true;
|
||||
}
|
||||
return fileTypeMainType.equals(mimeTypeMainType);
|
||||
@NonNull
|
||||
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> fileList = new LinkedList<>();
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
if (found != null) {
|
||||
Collections.addAll(fileList, found);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
}
|
||||
|
||||
public static String stripExtension(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> files = new LinkedList<>();
|
||||
internalListFilesDeep(files, directory, fileFilter);
|
||||
return files;
|
||||
}
|
||||
int pos = str.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return str;
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull Collection<File> files,
|
||||
@Nullable FileFilter fileFilter) {
|
||||
List<File> resFiles = new LinkedList<>();
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(resFiles, file, fileFilter);
|
||||
} else if (fileFilter == null || fileFilter.accept(file)) {
|
||||
resFiles.add(file);
|
||||
}
|
||||
}
|
||||
return resFiles;
|
||||
}
|
||||
return str.substring(0, pos);
|
||||
}
|
||||
|
||||
public static String readFromStream(InputStream is) throws Exception {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(line);
|
||||
private static void internalListFilesDeep(@NonNull Collection<File> files,
|
||||
@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
|
||||
if (found != null) {
|
||||
for (File file : found) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(files, file, fileFilter);
|
||||
} else {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String read(File file) throws Exception {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
String ret = readFromStream(fin);
|
||||
fin.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isExternalMemoryAvailable() {
|
||||
Boolean isSDPresent = Environment.getExternalStorageState()
|
||||
.equals(android.os.Environment.MEDIA_MOUNTED);
|
||||
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
|
||||
|
||||
if (isSDSupportedDevice && isSDPresent) {
|
||||
// yes SD-card is present
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
// Sorry
|
||||
public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) {
|
||||
if (mimeType == null || mimeType.equals("*/*")) {
|
||||
return true;
|
||||
} else {
|
||||
// get the file mime type
|
||||
String filename = file.toURI().toString();
|
||||
int dotPos = filename.lastIndexOf('.');
|
||||
if (dotPos == -1) {
|
||||
return false;
|
||||
}
|
||||
String fileExtension = filename.substring(dotPos + 1).toLowerCase();
|
||||
String fileType = mimeTypeMap.getMimeTypeFromExtension(fileExtension);
|
||||
if (fileType == null) {
|
||||
return false;
|
||||
}
|
||||
// check the 'type/subtype' pattern
|
||||
if (fileType.equals(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
// check the 'type/*' pattern
|
||||
int mimeTypeDelimiter = mimeType.lastIndexOf('/');
|
||||
if (mimeTypeDelimiter == -1) {
|
||||
return false;
|
||||
}
|
||||
String mimeTypeMainType = mimeType.substring(0, mimeTypeDelimiter);
|
||||
String mimeTypeSubtype = mimeType.substring(mimeTypeDelimiter + 1);
|
||||
if (!mimeTypeSubtype.equals("*")) {
|
||||
return false;
|
||||
}
|
||||
int fileTypeDelimiter = fileType.lastIndexOf('/');
|
||||
if (fileTypeDelimiter == -1) {
|
||||
return false;
|
||||
}
|
||||
String fileTypeMainType = fileType.substring(0, fileTypeDelimiter);
|
||||
if (fileTypeMainType.equals(mimeTypeMainType)) {
|
||||
return true;
|
||||
}
|
||||
return fileTypeMainType.equals(mimeTypeMainType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static File safeGetCanonicalFile(File file) {
|
||||
try {
|
||||
return file.getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsoluteFile();
|
||||
public static String stripExtension(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
int pos = str.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, pos);
|
||||
}
|
||||
|
||||
public static String readFromStream(InputStream is) throws Exception {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(line);
|
||||
}
|
||||
reader.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String read(File file) throws Exception {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
String ret = readFromStream(fin);
|
||||
fin.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isExternalMemoryAvailable() {
|
||||
Boolean isSDPresent = Environment.getExternalStorageState()
|
||||
.equals(android.os.Environment.MEDIA_MOUNTED);
|
||||
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
|
||||
|
||||
if (isSDSupportedDevice && isSDPresent) {
|
||||
// yes SD-card is present
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
// Sorry
|
||||
}
|
||||
}
|
||||
|
||||
public static File safeGetCanonicalFile(File file) {
|
||||
try {
|
||||
return file.getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsoluteFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.graphics.PorterDuff;
|
|||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.media.ExifInterface;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -19,204 +20,204 @@ import java.io.IOException;
|
|||
*/
|
||||
public class ImageUtil {
|
||||
|
||||
private static final int TOLERANCE = 20;
|
||||
// Alpha amount for which values below are considered transparent.
|
||||
private static final int ALPHA_TOLERANCE = 50;
|
||||
private static int[] mTempBuffer;
|
||||
private static final int TOLERANCE = 20;
|
||||
// Alpha amount for which values below are considered transparent.
|
||||
private static final int ALPHA_TOLERANCE = 50;
|
||||
private static int[] mTempBuffer;
|
||||
|
||||
private ImageUtil() {
|
||||
private ImageUtil() {
|
||||
|
||||
}
|
||||
|
||||
public static boolean isGrayscale(Bitmap bitmap) {
|
||||
final int height = bitmap.getHeight();
|
||||
final int width = bitmap.getWidth();
|
||||
int size = height * width;
|
||||
ensureBufferSize(size);
|
||||
bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!isGrayscale(mTempBuffer[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that {@code mTempBuffer} has at least length {@code size}.
|
||||
*/
|
||||
private static void ensureBufferSize(int size) {
|
||||
if (mTempBuffer == null || mTempBuffer.length < size) {
|
||||
mTempBuffer = new int[size];
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap setBitmapColor(Bitmap bitmap, int color) {
|
||||
Bitmap result = Bitmap
|
||||
.createBitmap(bitmap, 0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
|
||||
Paint paint = new Paint();
|
||||
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
|
||||
|
||||
Canvas canvas = new Canvas(result);
|
||||
canvas.drawBitmap(result, 0, 0, paint);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isGrayscale(int color) {
|
||||
int alpha = 0xFF & (color >> 24);
|
||||
if (alpha < ALPHA_TOLERANCE) {
|
||||
return true;
|
||||
}
|
||||
int r = 0xFF & (color >> 16);
|
||||
int g = 0xFF & (color >> 8);
|
||||
int b = 0xFF & color;
|
||||
return Math.abs(r - g) < TOLERANCE
|
||||
&& Math.abs(r - b) < TOLERANCE
|
||||
&& Math.abs(g - b) < TOLERANCE;
|
||||
} // Amount (max is 255) that two channels can differ before the color is no longer "gray".
|
||||
|
||||
public static Bitmap resizeBitmap(@NonNull Bitmap src, int maxForSmallerSize) {
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
|
||||
final int dstWidth;
|
||||
final int dstHeight;
|
||||
|
||||
if (width < height) {
|
||||
if (maxForSmallerSize >= width) {
|
||||
return src;
|
||||
}
|
||||
float ratio = (float) height / width;
|
||||
dstWidth = maxForSmallerSize;
|
||||
dstHeight = Math.round(maxForSmallerSize * ratio);
|
||||
} else {
|
||||
if (maxForSmallerSize >= height) {
|
||||
return src;
|
||||
}
|
||||
float ratio = (float) width / height;
|
||||
dstWidth = Math.round(maxForSmallerSize * ratio);
|
||||
dstHeight = maxForSmallerSize;
|
||||
}
|
||||
|
||||
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
|
||||
}
|
||||
|
||||
public static int calculateInSampleSize(int width, int height, int reqWidth) {
|
||||
// setting reqWidth matching to desired 1:1 ratio and screen-size
|
||||
if (width < height) {
|
||||
reqWidth = (height / width) * reqWidth;
|
||||
} else {
|
||||
reqWidth = (width / height) * reqWidth;
|
||||
public static boolean isGrayscale(Bitmap bitmap) {
|
||||
final int height = bitmap.getHeight();
|
||||
final int width = bitmap.getWidth();
|
||||
int size = height * width;
|
||||
ensureBufferSize(size);
|
||||
bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!isGrayscale(mTempBuffer[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (height > reqWidth || width > reqWidth) {
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) > reqWidth
|
||||
&& (halfWidth / inSampleSize) > reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
/**
|
||||
* Makes sure that {@code mTempBuffer} has at least length {@code size}.
|
||||
*/
|
||||
private static void ensureBufferSize(int size) {
|
||||
if (mTempBuffer == null || mTempBuffer.length < size) {
|
||||
mTempBuffer = new int[size];
|
||||
}
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
public static Bitmap setBitmapColor(Bitmap bitmap, int color) {
|
||||
Bitmap result = Bitmap
|
||||
.createBitmap(bitmap, 0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
|
||||
Paint paint = new Paint();
|
||||
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
|
||||
|
||||
static File compressImage(File imageFile, int reqWidth, int reqHeight,
|
||||
Bitmap.CompressFormat compressFormat, int quality, String destinationPath)
|
||||
throws IOException {
|
||||
FileOutputStream fileOutputStream = null;
|
||||
File file = new File(destinationPath).getParentFile();
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(destinationPath);
|
||||
// write the compressed bitmap at the destination specified by destinationPath.
|
||||
decodeSampledBitmapFromFile(imageFile, reqWidth, reqHeight)
|
||||
.compress(compressFormat, quality, fileOutputStream);
|
||||
} finally {
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
}
|
||||
Canvas canvas = new Canvas(result);
|
||||
canvas.drawBitmap(result, 0, 0, paint);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return new File(destinationPath);
|
||||
}
|
||||
public static boolean isGrayscale(int color) {
|
||||
int alpha = 0xFF & (color >> 24);
|
||||
if (alpha < ALPHA_TOLERANCE) {
|
||||
return true;
|
||||
}
|
||||
int r = 0xFF & (color >> 16);
|
||||
int g = 0xFF & (color >> 8);
|
||||
int b = 0xFF & color;
|
||||
return Math.abs(r - g) < TOLERANCE
|
||||
&& Math.abs(r - b) < TOLERANCE
|
||||
&& Math.abs(g - b) < TOLERANCE;
|
||||
} // Amount (max is 255) that two channels can differ before the color is no longer "gray".
|
||||
|
||||
static Bitmap decodeSampledBitmapFromFile(File imageFile, int reqWidth, int reqHeight)
|
||||
throws IOException {
|
||||
// First decode with inJustDecodeBounds=true to check dimensions
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
|
||||
public static Bitmap resizeBitmap(@NonNull Bitmap src, int maxForSmallerSize) {
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
|
||||
// Calculate inSampleSize
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
final int dstWidth;
|
||||
final int dstHeight;
|
||||
|
||||
// Decode bitmap with inSampleSize set
|
||||
options.inJustDecodeBounds = false;
|
||||
if (width < height) {
|
||||
if (maxForSmallerSize >= width) {
|
||||
return src;
|
||||
}
|
||||
float ratio = (float) height / width;
|
||||
dstWidth = maxForSmallerSize;
|
||||
dstHeight = Math.round(maxForSmallerSize * ratio);
|
||||
} else {
|
||||
if (maxForSmallerSize >= height) {
|
||||
return src;
|
||||
}
|
||||
float ratio = (float) width / height;
|
||||
dstWidth = Math.round(maxForSmallerSize * ratio);
|
||||
dstHeight = maxForSmallerSize;
|
||||
}
|
||||
|
||||
Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
|
||||
|
||||
//check the rotation of the image and display it properly
|
||||
ExifInterface exif;
|
||||
exif = new ExifInterface(imageFile.getAbsolutePath());
|
||||
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
|
||||
Matrix matrix = new Matrix();
|
||||
if (orientation == 6) {
|
||||
matrix.postRotate(90);
|
||||
} else if (orientation == 3) {
|
||||
matrix.postRotate(180);
|
||||
} else if (orientation == 8) {
|
||||
matrix.postRotate(270);
|
||||
}
|
||||
scaledBitmap = Bitmap
|
||||
.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
|
||||
true);
|
||||
return scaledBitmap;
|
||||
}
|
||||
|
||||
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth,
|
||||
int reqHeight) {
|
||||
// Raw height and width of image
|
||||
final int height = options.outHeight;
|
||||
final int width = options.outWidth;
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (height > reqHeight || width > reqWidth) {
|
||||
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
public static int calculateInSampleSize(int width, int height, int reqWidth) {
|
||||
// setting reqWidth matching to desired 1:1 ratio and screen-size
|
||||
if (width < height) {
|
||||
reqWidth = (height / width) * reqWidth;
|
||||
} else {
|
||||
reqWidth = (width / height) * reqWidth;
|
||||
}
|
||||
|
||||
public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
int inSampleSize = 1;
|
||||
|
||||
float bitmapRatio = (float) width / (float) height;
|
||||
if (bitmapRatio > 1) {
|
||||
width = maxSize;
|
||||
height = (int) (width / bitmapRatio);
|
||||
} else {
|
||||
height = maxSize;
|
||||
width = (int) (height * bitmapRatio);
|
||||
if (height > reqWidth || width > reqWidth) {
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) > reqWidth
|
||||
&& (halfWidth / inSampleSize) > reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
static File compressImage(File imageFile, int reqWidth, int reqHeight,
|
||||
Bitmap.CompressFormat compressFormat, int quality, String destinationPath)
|
||||
throws IOException {
|
||||
FileOutputStream fileOutputStream = null;
|
||||
File file = new File(destinationPath).getParentFile();
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(destinationPath);
|
||||
// write the compressed bitmap at the destination specified by destinationPath.
|
||||
decodeSampledBitmapFromFile(imageFile, reqWidth, reqHeight)
|
||||
.compress(compressFormat, quality, fileOutputStream);
|
||||
} finally {
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
return new File(destinationPath);
|
||||
}
|
||||
|
||||
static Bitmap decodeSampledBitmapFromFile(File imageFile, int reqWidth, int reqHeight)
|
||||
throws IOException {
|
||||
// First decode with inJustDecodeBounds=true to check dimensions
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
|
||||
|
||||
// Calculate inSampleSize
|
||||
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
|
||||
|
||||
// Decode bitmap with inSampleSize set
|
||||
options.inJustDecodeBounds = false;
|
||||
|
||||
Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
|
||||
|
||||
//check the rotation of the image and display it properly
|
||||
ExifInterface exif;
|
||||
exif = new ExifInterface(imageFile.getAbsolutePath());
|
||||
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
|
||||
Matrix matrix = new Matrix();
|
||||
if (orientation == 6) {
|
||||
matrix.postRotate(90);
|
||||
} else if (orientation == 3) {
|
||||
matrix.postRotate(180);
|
||||
} else if (orientation == 8) {
|
||||
matrix.postRotate(270);
|
||||
}
|
||||
scaledBitmap = Bitmap
|
||||
.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
|
||||
true);
|
||||
return scaledBitmap;
|
||||
}
|
||||
|
||||
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth,
|
||||
int reqHeight) {
|
||||
// Raw height and width of image
|
||||
final int height = options.outHeight;
|
||||
final int width = options.outWidth;
|
||||
int inSampleSize = 1;
|
||||
|
||||
if (height > reqHeight || width > reqWidth) {
|
||||
|
||||
final int halfHeight = height / 2;
|
||||
final int halfWidth = width / 2;
|
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
|
||||
// height and width larger than the requested height and width.
|
||||
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
|
||||
inSampleSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
|
||||
float bitmapRatio = (float) width / (float) height;
|
||||
if (bitmapRatio > 1) {
|
||||
width = maxSize;
|
||||
height = (int) (width / bitmapRatio);
|
||||
} else {
|
||||
height = maxSize;
|
||||
width = (int) (height * bitmapRatio);
|
||||
}
|
||||
return Bitmap.createScaledBitmap(image, width, height, true);
|
||||
}
|
||||
return Bitmap.createScaledBitmap(image, width, height, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +1,70 @@
|
|||
package code.name.monkey.retromusic.util;
|
||||
|
||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum.Album.Image;
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum.Album.Image;
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist;
|
||||
|
||||
public class LastFMUtil {
|
||||
|
||||
public static String getLargestAlbumImageUrl(List<Image> list) {
|
||||
Map hashMap = new HashMap();
|
||||
for (Image image : list) {
|
||||
Object obj = null;
|
||||
String size = image.getSize();
|
||||
if (size == null) {
|
||||
obj = ImageSize.UNKNOWN;
|
||||
} else {
|
||||
try {
|
||||
obj = ImageSize.valueOf(size.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
public static String getLargestAlbumImageUrl(List<Image> list) {
|
||||
Map hashMap = new HashMap();
|
||||
for (Image image : list) {
|
||||
Object obj = null;
|
||||
String size = image.getSize();
|
||||
if (size == null) {
|
||||
obj = ImageSize.UNKNOWN;
|
||||
} else {
|
||||
try {
|
||||
obj = ImageSize.valueOf(size.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
hashMap.put(obj, image.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
hashMap.put(obj, image.getText());
|
||||
}
|
||||
return getLargestImageUrl(hashMap);
|
||||
}
|
||||
return getLargestImageUrl(hashMap);
|
||||
}
|
||||
|
||||
public static String getLargestArtistImageUrl(List<LastFmArtist.Artist.Image> list) {
|
||||
Map hashMap = new HashMap();
|
||||
for (LastFmArtist.Artist.Image image : list) {
|
||||
Object obj = null;
|
||||
String size = image.getSize();
|
||||
if (size == null) {
|
||||
obj = ImageSize.UNKNOWN;
|
||||
} else {
|
||||
try {
|
||||
obj = ImageSize.valueOf(size.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
public static String getLargestArtistImageUrl(List<LastFmArtist.Artist.Image> list) {
|
||||
Map hashMap = new HashMap();
|
||||
for (LastFmArtist.Artist.Image image : list) {
|
||||
Object obj = null;
|
||||
String size = image.getSize();
|
||||
if (size == null) {
|
||||
obj = ImageSize.UNKNOWN;
|
||||
} else {
|
||||
try {
|
||||
obj = ImageSize.valueOf(size.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
hashMap.put(obj, image.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
hashMap.put(obj, image.getText());
|
||||
}
|
||||
return getLargestImageUrl(hashMap);
|
||||
}
|
||||
return getLargestImageUrl(hashMap);
|
||||
}
|
||||
|
||||
private static String getLargestImageUrl(Map<ImageSize, String> map) {
|
||||
return map.containsKey(ImageSize.MEGA) ? map.get(ImageSize.MEGA)
|
||||
: map.containsKey(ImageSize.EXTRALARGE) ? map.get(ImageSize.EXTRALARGE)
|
||||
: map.containsKey(ImageSize.LARGE) ? map.get(ImageSize.LARGE)
|
||||
private static String getLargestImageUrl(Map<ImageSize, String> map) {
|
||||
return map.containsKey(ImageSize.MEGA) ? map.get(ImageSize.MEGA)
|
||||
: map.containsKey(ImageSize.EXTRALARGE) ? map.get(ImageSize.EXTRALARGE)
|
||||
: map.containsKey(ImageSize.LARGE) ? map.get(ImageSize.LARGE)
|
||||
: map.containsKey(ImageSize.MEDIUM) ? map.get(ImageSize.MEDIUM)
|
||||
: map.containsKey(ImageSize.SMALL) ? map.get(ImageSize.SMALL)
|
||||
: map.containsKey(ImageSize.UNKNOWN) ? map.get(ImageSize.UNKNOWN) : null;
|
||||
}
|
||||
: map.containsKey(ImageSize.SMALL) ? map.get(ImageSize.SMALL)
|
||||
: map.containsKey(ImageSize.UNKNOWN) ? map.get(ImageSize.UNKNOWN) : null;
|
||||
}
|
||||
|
||||
private enum ImageSize {
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE,
|
||||
EXTRALARGE,
|
||||
MEGA,
|
||||
UNKNOWN
|
||||
}
|
||||
private enum ImageSize {
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE,
|
||||
EXTRALARGE,
|
||||
MEGA,
|
||||
UNKNOWN
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,17 @@ import android.support.v4.content.FileProvider;
|
|||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistLoader;
|
||||
|
@ -27,384 +38,376 @@ import code.name.monkey.retromusic.model.Playlist;
|
|||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics;
|
||||
import io.reactivex.Observable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
|
||||
public class MusicUtil {
|
||||
|
||||
public static final String TAG = MusicUtil.class.getSimpleName();
|
||||
private static Playlist playlist;
|
||||
public static final String TAG = MusicUtil.class.getSimpleName();
|
||||
private static Playlist playlist;
|
||||
|
||||
public static Uri getMediaStoreAlbumCoverUri(int albumId) {
|
||||
final Uri sArtworkUri = Uri
|
||||
.parse("content://media/external/audio/albumart");
|
||||
public static Uri getMediaStoreAlbumCoverUri(int albumId) {
|
||||
final Uri sArtworkUri = Uri
|
||||
.parse("content://media/external/audio/albumart");
|
||||
|
||||
return ContentUris.withAppendedId(sArtworkUri, albumId);
|
||||
}
|
||||
|
||||
public static Uri getSongFileUri(int songId) {
|
||||
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Intent createShareSongFileIntent(@NonNull final Song song, Context context) {
|
||||
try {
|
||||
|
||||
return new Intent()
|
||||
.setAction(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_STREAM,
|
||||
FileProvider.getUriForFile(context,
|
||||
context.getApplicationContext().getPackageName(),
|
||||
new File(song.data)))
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.setType("audio/*");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// TODO the path is most likely not like /storage/emulated/0/... but something like /storage/28C7-75B0/...
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, "Could not share this file, I'm aware of the issue.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return new Intent();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setRingtone(@NonNull final Context context, final int id) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Uri uri = getSongFileUri(id);
|
||||
try {
|
||||
final ContentValues values = new ContentValues(2);
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_RINGTONE, "1");
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_ALARM, "1");
|
||||
resolver.update(uri, values, null, null);
|
||||
} catch (@NonNull final UnsupportedOperationException ignored) {
|
||||
return;
|
||||
return ContentUris.withAppendedId(sArtworkUri, albumId);
|
||||
}
|
||||
|
||||
try {
|
||||
Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.MediaColumns.TITLE},
|
||||
BaseColumns._ID + "=?",
|
||||
new String[]{String.valueOf(id)},
|
||||
null);
|
||||
try {
|
||||
if (cursor != null && cursor.getCount() == 1) {
|
||||
cursor.moveToFirst();
|
||||
Settings.System.putString(resolver, Settings.System.RINGTONE, uri.toString());
|
||||
final String message = context
|
||||
.getString(R.string.x_has_been_set_as_ringtone, cursor.getString(0));
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
public static Uri getSongFileUri(int songId) {
|
||||
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Intent createShareSongFileIntent(@NonNull final Song song, Context context) {
|
||||
try {
|
||||
|
||||
return new Intent()
|
||||
.setAction(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_STREAM,
|
||||
FileProvider.getUriForFile(context,
|
||||
context.getApplicationContext().getPackageName(),
|
||||
new File(song.data)))
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.setType("audio/*");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// TODO the path is most likely not like /storage/emulated/0/... but something like /storage/28C7-75B0/...
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, "Could not share this file, I'm aware of the issue.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return new Intent();
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getArtistInfoString(@NonNull final Context context,
|
||||
@NonNull final Artist artist) {
|
||||
int albumCount = artist.getAlbumCount();
|
||||
int songCount = artist.getSongCount();
|
||||
String albumString = albumCount == 1 ? context.getResources().getString(R.string.album)
|
||||
: context.getResources().getString(R.string.albums);
|
||||
String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
return albumCount + " " + albumString + " • " + songCount + " " + songString;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getArtistInfoStringSmall(@NonNull final Context context,
|
||||
@NonNull final Artist artist) {
|
||||
int songCount = artist.getSongCount();
|
||||
String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
return songCount + " " + songString;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getPlaylistInfoString(@NonNull final Context context,
|
||||
@NonNull List<Song> songs) {
|
||||
final int songCount = songs.size();
|
||||
final String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
|
||||
long duration = 0;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
duration += songs.get(i).duration;
|
||||
}
|
||||
|
||||
return songCount + " " + songString + " • " + MusicUtil.getReadableDurationString(duration);
|
||||
}
|
||||
|
||||
public static String getReadableDurationString(long songDurationMillis) {
|
||||
long minutes = (songDurationMillis / 1000) / 60;
|
||||
long seconds = (songDurationMillis / 1000) % 60;
|
||||
if (minutes < 60) {
|
||||
return String.format(Locale.getDefault(), "%01d:%02d", minutes, seconds);
|
||||
} else {
|
||||
long hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
//iTunes uses for example 1002 for track 2 CD1 or 3011 for track 11 CD3.
|
||||
//this method converts those values to normal tracknumbers
|
||||
public static int getFixedTrackNumber(int trackNumberToFix) {
|
||||
return trackNumberToFix % 1000;
|
||||
}
|
||||
|
||||
public static void insertAlbumArt(@NonNull Context context, int albumId, String path) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
|
||||
contentResolver.delete(ContentUris.withAppendedId(artworkUri, albumId), null, null);
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("album_id", albumId);
|
||||
values.put("_data", path);
|
||||
|
||||
contentResolver.insert(artworkUri, values);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static File createAlbumArtFile() {
|
||||
return new File(createAlbumArtDir(), String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private static File createAlbumArtDir() {
|
||||
File albumArtDir = new File(Environment.getExternalStorageDirectory(), "/albumthumbs/");
|
||||
if (!albumArtDir.exists()) {
|
||||
albumArtDir.mkdirs();
|
||||
try {
|
||||
new File(albumArtDir, ".nomedia").createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return albumArtDir;
|
||||
}
|
||||
|
||||
public static void deleteTracks(@NonNull final Activity activity,
|
||||
@NonNull final List<Song> songs) {
|
||||
final String[] projection = new String[]{
|
||||
BaseColumns._ID, MediaStore.MediaColumns.DATA
|
||||
};
|
||||
final StringBuilder selection = new StringBuilder();
|
||||
selection.append(BaseColumns._ID + " IN (");
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
selection.append(songs.get(i).id);
|
||||
if (i < songs.size() - 1) {
|
||||
selection.append(",");
|
||||
}
|
||||
}
|
||||
selection.append(")");
|
||||
|
||||
try {
|
||||
final Cursor cursor = activity.getContentResolver().query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection.toString(),
|
||||
null, null);
|
||||
if (cursor != null) {
|
||||
// Step 1: Remove selected tracks from the current playlist, as well
|
||||
// as from the album art cache
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
final int id = cursor.getInt(0);
|
||||
Song song = SongLoader.getSong(activity, id).blockingFirst();
|
||||
MusicPlayerRemote.removeFromQueue(song);
|
||||
cursor.moveToNext();
|
||||
public static void setRingtone(@NonNull final Context context, final int id) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Uri uri = getSongFileUri(id);
|
||||
try {
|
||||
final ContentValues values = new ContentValues(2);
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_RINGTONE, "1");
|
||||
values.put(MediaStore.Audio.AudioColumns.IS_ALARM, "1");
|
||||
resolver.update(uri, values, null, null);
|
||||
} catch (@NonNull final UnsupportedOperationException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 2: Remove selected tracks from the database
|
||||
activity.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
selection.toString(), null);
|
||||
|
||||
// Step 3: Remove files from card
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
final String name = cursor.getString(1);
|
||||
try { // File.delete can throw a security exception
|
||||
final File f = new File(name);
|
||||
if (!f.delete()) {
|
||||
// I'm not sure if we'd ever get here (deletion would
|
||||
// have to fail, but no exception thrown)
|
||||
Log.e("MusicUtils", "Failed to delete file " + name);
|
||||
}
|
||||
cursor.moveToNext();
|
||||
} catch (@NonNull final SecurityException ex) {
|
||||
cursor.moveToNext();
|
||||
} catch (NullPointerException e) {
|
||||
Log.e("MusicUtils", "Failed to find file " + name);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
activity.getContentResolver().notifyChange(Uri.parse("content://media"), null);
|
||||
Toast.makeText(activity, activity.getString(R.string.deleted_x_songs, songs.size()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteAlbumArt(@NonNull Context context, int albumId) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
Uri localUri = Uri.parse("content://media/external/audio/albumart");
|
||||
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static String getLyrics(Song song) {
|
||||
String lyrics = null;
|
||||
|
||||
File file = new File(song.data);
|
||||
|
||||
try {
|
||||
lyrics = AudioFileIO.read(file).getTagOrCreateDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (lyrics == null || lyrics.trim().isEmpty() || !AbsSynchronizedLyrics
|
||||
.isSynchronized(lyrics)) {
|
||||
File dir = file.getAbsoluteFile().getParentFile();
|
||||
|
||||
if (dir != null && dir.exists() && dir.isDirectory()) {
|
||||
String format = ".*%s.*\\.(lrc|txt)";
|
||||
String filename = Pattern.quote(FileUtil.stripExtension(file.getName()));
|
||||
String songtitle = Pattern.quote(song.title);
|
||||
|
||||
final ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
patterns.add(Pattern.compile(String.format(format, filename),
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
|
||||
patterns.add(Pattern.compile(String.format(format, songtitle),
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
|
||||
|
||||
File[] files = dir.listFiles(f -> {
|
||||
for (Pattern pattern : patterns) {
|
||||
if (pattern.matcher(f.getName()).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (files != null && files.length > 0) {
|
||||
for (File f : files) {
|
||||
try {
|
||||
Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.MediaColumns.TITLE},
|
||||
BaseColumns._ID + "=?",
|
||||
new String[]{String.valueOf(id)},
|
||||
null);
|
||||
try {
|
||||
String newLyrics = FileUtil.read(f);
|
||||
if (newLyrics != null && !newLyrics.trim().isEmpty()) {
|
||||
if (AbsSynchronizedLyrics.isSynchronized(newLyrics)) {
|
||||
return newLyrics;
|
||||
if (cursor != null && cursor.getCount() == 1) {
|
||||
cursor.moveToFirst();
|
||||
Settings.System.putString(resolver, Settings.System.RINGTONE, uri.toString());
|
||||
final String message = context
|
||||
.getString(R.string.x_has_been_set_as_ringtone, cursor.getString(0));
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
lyrics = newLyrics;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lyrics;
|
||||
}
|
||||
|
||||
public static void toggleFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
if (isFavorite(context, song)) {
|
||||
PlaylistsUtil
|
||||
.removeFromPlaylist(context, song, getFavoritesPlaylist(context).blockingFirst().id);
|
||||
} else {
|
||||
PlaylistsUtil
|
||||
.addToPlaylist(context, song, getOrCreateFavoritesPlaylist(context).blockingFirst().id,
|
||||
false);
|
||||
@NonNull
|
||||
public static String getArtistInfoString(@NonNull final Context context,
|
||||
@NonNull final Artist artist) {
|
||||
int albumCount = artist.getAlbumCount();
|
||||
int songCount = artist.getSongCount();
|
||||
String albumString = albumCount == 1 ? context.getResources().getString(R.string.album)
|
||||
: context.getResources().getString(R.string.albums);
|
||||
String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
return albumCount + " " + albumString + " • " + songCount + " " + songString;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFavoritePlaylist(@NonNull final Context context,
|
||||
@NonNull final Playlist playlist) {
|
||||
return playlist.name != null && playlist.name.equals(context.getString(R.string.favorites));
|
||||
}
|
||||
@NonNull
|
||||
public static String getArtistInfoStringSmall(@NonNull final Context context,
|
||||
@NonNull final Artist artist) {
|
||||
int songCount = artist.getSongCount();
|
||||
String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
return songCount + " " + songString;
|
||||
}
|
||||
|
||||
private static Observable<Playlist> getFavoritesPlaylist(@NonNull final Context context) {
|
||||
return PlaylistLoader.getPlaylist(context, context.getString(R.string.favorites));
|
||||
}
|
||||
@NonNull
|
||||
public static String getPlaylistInfoString(@NonNull final Context context,
|
||||
@NonNull List<Song> songs) {
|
||||
final int songCount = songs.size();
|
||||
final String songString = songCount == 1 ? context.getResources().getString(R.string.song)
|
||||
: context.getResources().getString(R.string.songs);
|
||||
|
||||
private static Observable<Playlist> getOrCreateFavoritesPlaylist(@NonNull final Context context) {
|
||||
return PlaylistLoader.getPlaylist(context,
|
||||
PlaylistsUtil.createPlaylist(context, context.getString(R.string.favorites)));
|
||||
}
|
||||
long duration = 0;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
duration += songs.get(i).duration;
|
||||
}
|
||||
|
||||
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
return songCount + " " + songString + " • " + MusicUtil.getReadableDurationString(duration);
|
||||
}
|
||||
|
||||
public static String getReadableDurationString(long songDurationMillis) {
|
||||
long minutes = (songDurationMillis / 1000) / 60;
|
||||
long seconds = (songDurationMillis / 1000) % 60;
|
||||
if (minutes < 60) {
|
||||
return String.format(Locale.getDefault(), "%01d:%02d", minutes, seconds);
|
||||
} else {
|
||||
long hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
return String.format(Locale.getDefault(), "%d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
//iTunes uses for example 1002 for track 2 CD1 or 3011 for track 11 CD3.
|
||||
//this method converts those values to normal tracknumbers
|
||||
public static int getFixedTrackNumber(int trackNumberToFix) {
|
||||
return trackNumberToFix % 1000;
|
||||
}
|
||||
|
||||
public static void insertAlbumArt(@NonNull Context context, int albumId, String path) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
|
||||
contentResolver.delete(ContentUris.withAppendedId(artworkUri, albumId), null, null);
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("album_id", albumId);
|
||||
values.put("_data", path);
|
||||
|
||||
contentResolver.insert(artworkUri, values);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static File createAlbumArtFile() {
|
||||
return new File(createAlbumArtDir(), String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private static File createAlbumArtDir() {
|
||||
File albumArtDir = new File(Environment.getExternalStorageDirectory(), "/albumthumbs/");
|
||||
if (!albumArtDir.exists()) {
|
||||
albumArtDir.mkdirs();
|
||||
try {
|
||||
new File(albumArtDir, ".nomedia").createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return albumArtDir;
|
||||
}
|
||||
|
||||
public static void deleteTracks(@NonNull final Activity activity,
|
||||
@NonNull final List<Song> songs) {
|
||||
final String[] projection = new String[]{
|
||||
BaseColumns._ID, MediaStore.MediaColumns.DATA
|
||||
};
|
||||
final StringBuilder selection = new StringBuilder();
|
||||
selection.append(BaseColumns._ID + " IN (");
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
selection.append(songs.get(i).id);
|
||||
if (i < songs.size() - 1) {
|
||||
selection.append(",");
|
||||
}
|
||||
}
|
||||
selection.append(")");
|
||||
|
||||
try {
|
||||
final Cursor cursor = activity.getContentResolver().query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection.toString(),
|
||||
null, null);
|
||||
if (cursor != null) {
|
||||
// Step 1: Remove selected tracks from the current playlist, as well
|
||||
// as from the album art cache
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
final int id = cursor.getInt(0);
|
||||
Song song = SongLoader.getSong(activity, id).blockingFirst();
|
||||
MusicPlayerRemote.removeFromQueue(song);
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
// Step 2: Remove selected tracks from the database
|
||||
activity.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
selection.toString(), null);
|
||||
|
||||
// Step 3: Remove files from card
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
final String name = cursor.getString(1);
|
||||
try { // File.delete can throw a security exception
|
||||
final File f = new File(name);
|
||||
if (!f.delete()) {
|
||||
// I'm not sure if we'd ever get here (deletion would
|
||||
// have to fail, but no exception thrown)
|
||||
Log.e("MusicUtils", "Failed to delete file " + name);
|
||||
}
|
||||
cursor.moveToNext();
|
||||
} catch (@NonNull final SecurityException ex) {
|
||||
cursor.moveToNext();
|
||||
} catch (NullPointerException e) {
|
||||
Log.e("MusicUtils", "Failed to find file " + name);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
activity.getContentResolver().notifyChange(Uri.parse("content://media"), null);
|
||||
Toast.makeText(activity, activity.getString(R.string.deleted_x_songs, songs.size()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteAlbumArt(@NonNull Context context, int albumId) {
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
Uri localUri = Uri.parse("content://media/external/audio/albumart");
|
||||
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static String getLyrics(Song song) {
|
||||
String lyrics = null;
|
||||
|
||||
File file = new File(song.data);
|
||||
|
||||
try {
|
||||
lyrics = AudioFileIO.read(file).getTagOrCreateDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (lyrics == null || lyrics.trim().isEmpty() || !AbsSynchronizedLyrics
|
||||
.isSynchronized(lyrics)) {
|
||||
File dir = file.getAbsoluteFile().getParentFile();
|
||||
|
||||
if (dir != null && dir.exists() && dir.isDirectory()) {
|
||||
String format = ".*%s.*\\.(lrc|txt)";
|
||||
String filename = Pattern.quote(FileUtil.stripExtension(file.getName()));
|
||||
String songtitle = Pattern.quote(song.title);
|
||||
|
||||
final ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
patterns.add(Pattern.compile(String.format(format, filename),
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
|
||||
patterns.add(Pattern.compile(String.format(format, songtitle),
|
||||
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
|
||||
|
||||
File[] files = dir.listFiles(f -> {
|
||||
for (Pattern pattern : patterns) {
|
||||
if (pattern.matcher(f.getName()).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (files != null && files.length > 0) {
|
||||
for (File f : files) {
|
||||
try {
|
||||
String newLyrics = FileUtil.read(f);
|
||||
if (newLyrics != null && !newLyrics.trim().isEmpty()) {
|
||||
if (AbsSynchronizedLyrics.isSynchronized(newLyrics)) {
|
||||
return newLyrics;
|
||||
}
|
||||
lyrics = newLyrics;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lyrics;
|
||||
}
|
||||
|
||||
public static void toggleFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
if (isFavorite(context, song)) {
|
||||
PlaylistsUtil
|
||||
.removeFromPlaylist(context, song, getFavoritesPlaylist(context).blockingFirst().id);
|
||||
} else {
|
||||
PlaylistsUtil
|
||||
.addToPlaylist(context, song, getOrCreateFavoritesPlaylist(context).blockingFirst().id,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFavoritePlaylist(@NonNull final Context context,
|
||||
@NonNull final Playlist playlist) {
|
||||
return playlist.name != null && playlist.name.equals(context.getString(R.string.favorites));
|
||||
}
|
||||
|
||||
private static Observable<Playlist> getFavoritesPlaylist(@NonNull final Context context) {
|
||||
return PlaylistLoader.getPlaylist(context, context.getString(R.string.favorites));
|
||||
}
|
||||
|
||||
private static Observable<Playlist> getOrCreateFavoritesPlaylist(@NonNull final Context context) {
|
||||
return PlaylistLoader.getPlaylist(context,
|
||||
PlaylistsUtil.createPlaylist(context, context.getString(R.string.favorites)));
|
||||
}
|
||||
|
||||
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
/*return Observable.create(e -> getFavoritesPlaylist(context).subscribe(playlist1 -> {
|
||||
boolean isBoolean = PlaylistsUtil.doPlaylistContains(context, playlist1.id, song.id);
|
||||
e.onNext(isBoolean);
|
||||
e.onComplete();
|
||||
}));*/
|
||||
|
||||
//getFavoritesPlaylist(context).blockingFirst().id.subscribe(MusicUtil::setPlaylist);
|
||||
//return PlaylistsUtil.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.id);
|
||||
return PlaylistsUtil
|
||||
.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.id);
|
||||
}
|
||||
|
||||
public static boolean isArtistNameUnknown(@Nullable String artistName) {
|
||||
if (TextUtils.isEmpty(artistName)) {
|
||||
return false;
|
||||
//getFavoritesPlaylist(context).blockingFirst().id.subscribe(MusicUtil::setPlaylist);
|
||||
//return PlaylistsUtil.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.id);
|
||||
return PlaylistsUtil
|
||||
.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.id);
|
||||
}
|
||||
if (artistName.equals(Artist.UNKNOWN_ARTIST_DISPLAY_NAME)) {
|
||||
return true;
|
||||
}
|
||||
artistName = artistName.trim().toLowerCase();
|
||||
return artistName.equals("unknown") || artistName.equals("<unknown>");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSectionName(@Nullable String musicMediaTitle) {
|
||||
if (TextUtils.isEmpty(musicMediaTitle)) {
|
||||
return "";
|
||||
public static boolean isArtistNameUnknown(@Nullable String artistName) {
|
||||
if (TextUtils.isEmpty(artistName)) {
|
||||
return false;
|
||||
}
|
||||
if (artistName.equals(Artist.UNKNOWN_ARTIST_DISPLAY_NAME)) {
|
||||
return true;
|
||||
}
|
||||
artistName = artistName.trim().toLowerCase();
|
||||
return artistName.equals("unknown") || artistName.equals("<unknown>");
|
||||
}
|
||||
musicMediaTitle = musicMediaTitle.trim().toLowerCase();
|
||||
if (musicMediaTitle.startsWith("the ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(4);
|
||||
} else if (musicMediaTitle.startsWith("a ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(2);
|
||||
|
||||
@NonNull
|
||||
public static String getSectionName(@Nullable String musicMediaTitle) {
|
||||
if (TextUtils.isEmpty(musicMediaTitle)) {
|
||||
return "";
|
||||
}
|
||||
musicMediaTitle = musicMediaTitle.trim().toLowerCase();
|
||||
if (musicMediaTitle.startsWith("the ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(4);
|
||||
} else if (musicMediaTitle.startsWith("a ")) {
|
||||
musicMediaTitle = musicMediaTitle.substring(2);
|
||||
}
|
||||
if (musicMediaTitle.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return String.valueOf(musicMediaTitle.charAt(0)).toUpperCase();
|
||||
}
|
||||
if (musicMediaTitle.isEmpty()) {
|
||||
return "";
|
||||
|
||||
public static Playlist getPlaylist() {
|
||||
return playlist;
|
||||
}
|
||||
return String.valueOf(musicMediaTitle.charAt(0)).toUpperCase();
|
||||
}
|
||||
|
||||
public static Playlist getPlaylist() {
|
||||
return playlist;
|
||||
}
|
||||
|
||||
public static void setPlaylist(Playlist playlist) {
|
||||
MusicUtil.playlist = playlist;
|
||||
}
|
||||
|
||||
public static long getTotalDuration(@NonNull final Context context, @NonNull List<Song> songs) {
|
||||
long duration = 0;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
duration += songs.get(i).duration;
|
||||
public static void setPlaylist(Playlist playlist) {
|
||||
MusicUtil.playlist = playlist;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getYearString(int year) {
|
||||
return year > 0 ? String.valueOf(year) : "-";
|
||||
}
|
||||
public static long getTotalDuration(@NonNull final Context context, @NonNull List<Song> songs) {
|
||||
long duration = 0;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
duration += songs.get(i).duration;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getYearString(int year) {
|
||||
return year > 0 ? String.valueOf(year) : "-";
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,7 +25,6 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
|
@ -34,7 +33,6 @@ import android.view.Window;
|
|||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
|
|
|
@ -5,64 +5,64 @@ package code.name.monkey.retromusic.util;
|
|||
*/
|
||||
public class TempUtils {
|
||||
|
||||
// Enums
|
||||
public static final int TEMPO_STROLL = 0;
|
||||
public static final int TEMPO_WALK = 1;
|
||||
public static final int TEMPO_LIGHT_JOG = 2;
|
||||
public static final int TEMPO_JOG = 3;
|
||||
public static final int TEMPO_RUN = 4;
|
||||
public static final int TEMPO_SPRINT = 5;
|
||||
public static final int TEMPO_UNKNOWN = 6;
|
||||
// Enums
|
||||
public static final int TEMPO_STROLL = 0;
|
||||
public static final int TEMPO_WALK = 1;
|
||||
public static final int TEMPO_LIGHT_JOG = 2;
|
||||
public static final int TEMPO_JOG = 3;
|
||||
public static final int TEMPO_RUN = 4;
|
||||
public static final int TEMPO_SPRINT = 5;
|
||||
public static final int TEMPO_UNKNOWN = 6;
|
||||
|
||||
// take BPM as an int
|
||||
public static int getTempoFromBPM(int bpm) {
|
||||
// take BPM as an int
|
||||
public static int getTempoFromBPM(int bpm) {
|
||||
|
||||
// STROLL less than 60
|
||||
if (bpm < 60) {
|
||||
return TEMPO_STROLL;
|
||||
// STROLL less than 60
|
||||
if (bpm < 60) {
|
||||
return TEMPO_STROLL;
|
||||
}
|
||||
|
||||
// WALK between 60 and 70, or between 120 and 140
|
||||
else if (bpm < 70 || bpm >= 120 && bpm < 140) {
|
||||
return TEMPO_WALK;
|
||||
}
|
||||
|
||||
// LIGHT_JOG between 70 and 80, or between 140 and 160
|
||||
else if (bpm < 80 || bpm >= 140 && bpm < 160) {
|
||||
return TEMPO_LIGHT_JOG;
|
||||
}
|
||||
|
||||
// JOG between 80 and 90, or between 160 and 180
|
||||
else if (bpm < 90 || bpm >= 160 && bpm < 180) {
|
||||
return TEMPO_JOG;
|
||||
}
|
||||
|
||||
// RUN between 90 and 100, or between 180 and 200
|
||||
else if (bpm < 100 || bpm >= 180 && bpm < 200) {
|
||||
return TEMPO_RUN;
|
||||
}
|
||||
|
||||
// SPRINT between 100 and 120
|
||||
else if (bpm < 120) {
|
||||
return TEMPO_SPRINT;
|
||||
}
|
||||
|
||||
// UNKNOWN
|
||||
else {
|
||||
return TEMPO_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// WALK between 60 and 70, or between 120 and 140
|
||||
else if (bpm < 70 || bpm >= 120 && bpm < 140) {
|
||||
return TEMPO_WALK;
|
||||
}
|
||||
// take BPM as a string
|
||||
public static int getTempoFromBPM(String bpm) {
|
||||
// cast to an int from string
|
||||
try {
|
||||
// convert the string to an int
|
||||
return getTempoFromBPM(Integer.parseInt(bpm.trim()));
|
||||
} catch (NumberFormatException nfe) {
|
||||
|
||||
// LIGHT_JOG between 70 and 80, or between 140 and 160
|
||||
else if (bpm < 80 || bpm >= 140 && bpm < 160) {
|
||||
return TEMPO_LIGHT_JOG;
|
||||
//
|
||||
return TEMPO_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// JOG between 80 and 90, or between 160 and 180
|
||||
else if (bpm < 90 || bpm >= 160 && bpm < 180) {
|
||||
return TEMPO_JOG;
|
||||
}
|
||||
|
||||
// RUN between 90 and 100, or between 180 and 200
|
||||
else if (bpm < 100 || bpm >= 180 && bpm < 200) {
|
||||
return TEMPO_RUN;
|
||||
}
|
||||
|
||||
// SPRINT between 100 and 120
|
||||
else if (bpm < 120) {
|
||||
return TEMPO_SPRINT;
|
||||
}
|
||||
|
||||
// UNKNOWN
|
||||
else {
|
||||
return TEMPO_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// take BPM as a string
|
||||
public static int getTempoFromBPM(String bpm) {
|
||||
// cast to an int from string
|
||||
try {
|
||||
// convert the string to an int
|
||||
return getTempoFromBPM(Integer.parseInt(bpm.trim()));
|
||||
} catch (NumberFormatException nfe) {
|
||||
|
||||
//
|
||||
return TEMPO_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,52 +7,54 @@ import android.support.v4.view.ViewCompat;
|
|||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
public class ViewUtil {
|
||||
|
||||
public final static int RETRO_MUSIC_ANIM_TIME = 1000;
|
||||
public final static int RETRO_MUSIC_ANIM_TIME = 1000;
|
||||
|
||||
public static void setStatusBarHeight(final Context context, View statusBar) {
|
||||
ViewGroup.LayoutParams lp = statusBar.getLayoutParams();
|
||||
lp.height = getStatusBarHeight(context);
|
||||
statusBar.requestLayout();
|
||||
}
|
||||
|
||||
public static int getStatusBarHeight(final Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
public static void setStatusBarHeight(final Context context, View statusBar) {
|
||||
ViewGroup.LayoutParams lp = statusBar.getLayoutParams();
|
||||
lp.height = getStatusBarHeight(context);
|
||||
statusBar.requestLayout();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean hitTest(View v, int x, int y) {
|
||||
final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f);
|
||||
final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f);
|
||||
final int left = v.getLeft() + tx;
|
||||
final int right = v.getRight() + tx;
|
||||
final int top = v.getTop() + ty;
|
||||
final int bottom = v.getBottom() + ty;
|
||||
public static int getStatusBarHeight(final Context context) {
|
||||
int result = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
|
||||
}
|
||||
public static boolean hitTest(View v, int x, int y) {
|
||||
final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f);
|
||||
final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f);
|
||||
final int left = v.getLeft() + tx;
|
||||
final int right = v.getRight() + tx;
|
||||
final int top = v.getTop() + ty;
|
||||
final int bottom = v.getBottom() + ty;
|
||||
|
||||
public static void setUpFastScrollRecyclerViewColor(Context context,
|
||||
FastScrollRecyclerView recyclerView, int accentColor) {
|
||||
recyclerView.setPopupBgColor(accentColor);
|
||||
recyclerView.setPopupTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(accentColor)));
|
||||
recyclerView.setThumbColor(accentColor);
|
||||
recyclerView.setTrackColor(Color.TRANSPARENT);
|
||||
//recyclerView.setTrackColor(ColorUtil.withAlpha(ATHUtil.resolveColor(context, R.attr.colorControlNormal), 0.12f));
|
||||
}
|
||||
return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
|
||||
}
|
||||
|
||||
public static float convertDpToPixel(float dp, Resources resources) {
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return dp * metrics.density;
|
||||
}
|
||||
public static void setUpFastScrollRecyclerViewColor(Context context,
|
||||
FastScrollRecyclerView recyclerView, int accentColor) {
|
||||
recyclerView.setPopupBgColor(accentColor);
|
||||
recyclerView.setPopupTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(accentColor)));
|
||||
recyclerView.setThumbColor(accentColor);
|
||||
recyclerView.setTrackColor(Color.TRANSPARENT);
|
||||
//recyclerView.setTrackColor(ColorUtil.withAlpha(ATHUtil.resolveColor(context, R.attr.colorControlNormal), 0.12f));
|
||||
}
|
||||
|
||||
public static float convertDpToPixel(float dp, Resources resources) {
|
||||
DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
return dp * metrics.density;
|
||||
}
|
||||
}
|
|
@ -32,62 +32,62 @@ import android.graphics.drawable.Drawable;
|
|||
*/
|
||||
public class ImageGradientColorizer {
|
||||
|
||||
public Bitmap colorize(Drawable drawable, int backgroundColor, boolean isRtl) {
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
int size = Math.min(width, height);
|
||||
int widthInset = (width - size) / 2;
|
||||
int heightInset = (height - size) / 2;
|
||||
drawable = drawable.mutate();
|
||||
drawable.setBounds(-widthInset, -heightInset, width - widthInset, height - heightInset);
|
||||
Bitmap newBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(newBitmap);
|
||||
// Values to calculate the luminance of a color
|
||||
float lr = 0.2126f;
|
||||
float lg = 0.7152f;
|
||||
float lb = 0.0722f;
|
||||
// Extract the red, green, blue components of the color extraction color in
|
||||
// float and int form
|
||||
int tri = Color.red(backgroundColor);
|
||||
int tgi = Color.green(backgroundColor);
|
||||
int tbi = Color.blue(backgroundColor);
|
||||
float tr = tri / 255f;
|
||||
float tg = tgi / 255f;
|
||||
float tb = tbi / 255f;
|
||||
// Calculate the luminance of the color extraction color
|
||||
float cLum = (tr * lr + tg * lg + tb * lb) * 255;
|
||||
ColorMatrix m = new ColorMatrix(new float[]{
|
||||
lr, lg, lb, 0, tri - cLum,
|
||||
lr, lg, lb, 0, tgi - cLum,
|
||||
lr, lg, lb, 0, tbi - cLum,
|
||||
0, 0, 0, 1, 0,
|
||||
});
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
LinearGradient linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[]{0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
|
||||
new float[]{0.0f, 0.4f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
Bitmap fadeIn = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas fadeInCanvas = new Canvas(fadeIn);
|
||||
drawable.clearColorFilter();
|
||||
drawable.draw(fadeInCanvas);
|
||||
if (isRtl) {
|
||||
// Let's flip the gradient
|
||||
fadeInCanvas.translate(size, 0);
|
||||
fadeInCanvas.scale(-1, 1);
|
||||
public Bitmap colorize(Drawable drawable, int backgroundColor, boolean isRtl) {
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
int size = Math.min(width, height);
|
||||
int widthInset = (width - size) / 2;
|
||||
int heightInset = (height - size) / 2;
|
||||
drawable = drawable.mutate();
|
||||
drawable.setBounds(-widthInset, -heightInset, width - widthInset, height - heightInset);
|
||||
Bitmap newBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(newBitmap);
|
||||
// Values to calculate the luminance of a color
|
||||
float lr = 0.2126f;
|
||||
float lg = 0.7152f;
|
||||
float lb = 0.0722f;
|
||||
// Extract the red, green, blue components of the color extraction color in
|
||||
// float and int form
|
||||
int tri = Color.red(backgroundColor);
|
||||
int tgi = Color.green(backgroundColor);
|
||||
int tbi = Color.blue(backgroundColor);
|
||||
float tr = tri / 255f;
|
||||
float tg = tgi / 255f;
|
||||
float tb = tbi / 255f;
|
||||
// Calculate the luminance of the color extraction color
|
||||
float cLum = (tr * lr + tg * lg + tb * lb) * 255;
|
||||
ColorMatrix m = new ColorMatrix(new float[]{
|
||||
lr, lg, lb, 0, tri - cLum,
|
||||
lr, lg, lb, 0, tgi - cLum,
|
||||
lr, lg, lb, 0, tbi - cLum,
|
||||
0, 0, 0, 1, 0,
|
||||
});
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
LinearGradient linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[]{0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
|
||||
new float[]{0.0f, 0.4f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
Bitmap fadeIn = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas fadeInCanvas = new Canvas(fadeIn);
|
||||
drawable.clearColorFilter();
|
||||
drawable.draw(fadeInCanvas);
|
||||
if (isRtl) {
|
||||
// Let's flip the gradient
|
||||
fadeInCanvas.translate(size, 0);
|
||||
fadeInCanvas.scale(-1, 1);
|
||||
}
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
fadeInCanvas.drawPaint(paint);
|
||||
Paint coloredPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
coloredPaint.setColorFilter(new ColorMatrixColorFilter(m));
|
||||
coloredPaint.setAlpha((int) (0.5f * 255));
|
||||
canvas.drawBitmap(fadeIn, 0, 0, coloredPaint);
|
||||
linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[]{0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
|
||||
new float[]{0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
fadeInCanvas.drawPaint(paint);
|
||||
canvas.drawBitmap(fadeIn, 0, 0, null);
|
||||
return newBitmap;
|
||||
}
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
fadeInCanvas.drawPaint(paint);
|
||||
Paint coloredPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
coloredPaint.setColorFilter(new ColorMatrixColorFilter(m));
|
||||
coloredPaint.setAlpha((int) (0.5f * 255));
|
||||
canvas.drawBitmap(fadeIn, 0, 0, coloredPaint);
|
||||
linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[]{0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
|
||||
new float[]{0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
fadeInCanvas.drawPaint(paint);
|
||||
canvas.drawBitmap(fadeIn, 0, 0, null);
|
||||
return newBitmap;
|
||||
}
|
||||
}
|
|
@ -8,12 +8,11 @@ import android.graphics.drawable.BitmapDrawable;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.util.LayoutDirection;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
@ -46,13 +45,13 @@ public class MediaNotificationProcessor {
|
|||
private static final int RESIZE_BITMAP_AREA = 150 * 150;
|
||||
private final ImageGradientColorizer mColorizer;
|
||||
private final Context mContext;
|
||||
private float[] mFilteredBackgroundHsl = null;
|
||||
private Palette.Filter mBlackWhiteFilter = (rgb, hsl) -> !isWhiteOrBlack(hsl);
|
||||
/**
|
||||
* The context of the notification. This is the app context of the package posting the
|
||||
* notification.
|
||||
*/
|
||||
private final Context mPackageContext;
|
||||
private float[] mFilteredBackgroundHsl = null;
|
||||
private Palette.Filter mBlackWhiteFilter = (rgb, hsl) -> !isWhiteOrBlack(hsl);
|
||||
private boolean mIsLowPriority;
|
||||
private onColorThing onColorThing;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package code.name.monkey.retromusic.util.color;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
|
@ -9,15 +8,13 @@ import android.graphics.drawable.AnimationDrawable;
|
|||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.TextAppearanceSpan;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import code.name.monkey.retromusic.util.ImageUtil;
|
||||
import java.util.Arrays;
|
||||
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import code.name.monkey.retromusic.util.ImageUtil;
|
||||
|
||||
/**
|
||||
* Helper class to process legacy (Holo) notifications to make them look like quantum
|
||||
* notifications.
|
||||
|
@ -26,109 +23,109 @@ import java.util.WeakHashMap;
|
|||
*/
|
||||
public class NotificationColorUtil {
|
||||
|
||||
private static final String TAG = "NotificationColorUtil";
|
||||
private static final Object sLock = new Object();
|
||||
private static NotificationColorUtil sInstance;
|
||||
private static final String TAG = "NotificationColorUtil";
|
||||
private static final Object sLock = new Object();
|
||||
private static NotificationColorUtil sInstance;
|
||||
|
||||
private final WeakHashMap<Bitmap, Pair<Boolean, Integer>> mGrayscaleBitmapCache =
|
||||
new WeakHashMap<Bitmap, Pair<Boolean, Integer>>();
|
||||
private final WeakHashMap<Bitmap, Pair<Boolean, Integer>> mGrayscaleBitmapCache =
|
||||
new WeakHashMap<Bitmap, Pair<Boolean, Integer>>();
|
||||
|
||||
public static NotificationColorUtil getInstance() {
|
||||
synchronized (sLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new NotificationColorUtil();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a bitmap is grayscale. Grayscale here means "very close to a perfect gray".
|
||||
*
|
||||
* @param bitmap The bitmap to test.
|
||||
* @return Whether the bitmap is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Bitmap bitmap) {
|
||||
synchronized (sLock) {
|
||||
Pair<Boolean, Integer> cached = mGrayscaleBitmapCache.get(bitmap);
|
||||
if (cached != null) {
|
||||
if (cached.second == bitmap.getGenerationId()) {
|
||||
return cached.first;
|
||||
public static NotificationColorUtil getInstance() {
|
||||
synchronized (sLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new NotificationColorUtil();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean result;
|
||||
int generationId;
|
||||
|
||||
result = ImageUtil.isGrayscale(bitmap);
|
||||
// generationId and the check whether the Bitmap is grayscale can't be read atomically
|
||||
// here. However, since the thread is in the process of posting the notification, we can
|
||||
// assume that it doesn't modify the bitmap while we are checking the pixels.
|
||||
generationId = bitmap.getGenerationId();
|
||||
/**
|
||||
* Checks whether a bitmap is grayscale. Grayscale here means "very close to a perfect gray".
|
||||
*
|
||||
* @param bitmap The bitmap to test.
|
||||
* @return Whether the bitmap is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Bitmap bitmap) {
|
||||
synchronized (sLock) {
|
||||
Pair<Boolean, Integer> cached = mGrayscaleBitmapCache.get(bitmap);
|
||||
if (cached != null) {
|
||||
if (cached.second == bitmap.getGenerationId()) {
|
||||
return cached.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean result;
|
||||
int generationId;
|
||||
|
||||
synchronized (sLock) {
|
||||
mGrayscaleBitmapCache.put(bitmap, Pair.create(result, generationId));
|
||||
result = ImageUtil.isGrayscale(bitmap);
|
||||
// generationId and the check whether the Bitmap is grayscale can't be read atomically
|
||||
// here. However, since the thread is in the process of posting the notification, we can
|
||||
// assume that it doesn't modify the bitmap while we are checking the pixels.
|
||||
generationId = bitmap.getGenerationId();
|
||||
|
||||
synchronized (sLock) {
|
||||
mGrayscaleBitmapCache.put(bitmap, Pair.create(result, generationId));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a drawable is grayscale. Grayscale here means "very close to a perfect gray".
|
||||
*
|
||||
* @param d The drawable to test.
|
||||
* @return Whether the drawable is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Drawable d) {
|
||||
if (d == null) {
|
||||
return false;
|
||||
} else if (d instanceof BitmapDrawable) {
|
||||
BitmapDrawable bd = (BitmapDrawable) d;
|
||||
return bd.getBitmap() != null && isGrayscale(bd.getBitmap());
|
||||
} else if (d instanceof AnimationDrawable) {
|
||||
AnimationDrawable ad = (AnimationDrawable) d;
|
||||
int count = ad.getNumberOfFrames();
|
||||
return count > 0 && isGrayscale(ad.getFrame(0));
|
||||
} else if (d instanceof VectorDrawable) {
|
||||
// We just assume you're doing the right thing if using vectors
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
/**
|
||||
* Checks whether a drawable is grayscale. Grayscale here means "very close to a perfect gray".
|
||||
*
|
||||
* @param d The drawable to test.
|
||||
* @return Whether the drawable is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Drawable d) {
|
||||
if (d == null) {
|
||||
return false;
|
||||
} else if (d instanceof BitmapDrawable) {
|
||||
BitmapDrawable bd = (BitmapDrawable) d;
|
||||
return bd.getBitmap() != null && isGrayscale(bd.getBitmap());
|
||||
} else if (d instanceof AnimationDrawable) {
|
||||
AnimationDrawable ad = (AnimationDrawable) d;
|
||||
int count = ad.getNumberOfFrames();
|
||||
return count > 0 && isGrayscale(ad.getFrame(0));
|
||||
} else if (d instanceof VectorDrawable) {
|
||||
// We just assume you're doing the right thing if using vectors
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a drawable with a resoure id is grayscale. Grayscale here means "very close to a
|
||||
* perfect gray".
|
||||
*
|
||||
* @param context The context to load the drawable from.
|
||||
* @return Whether the drawable is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Context context, int drawableResId) {
|
||||
if (drawableResId != 0) {
|
||||
try {
|
||||
return isGrayscale(context.getDrawable(drawableResId));
|
||||
} catch (Resources.NotFoundException ex) {
|
||||
Log.e(TAG, "Drawable not found: " + drawableResId);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
/**
|
||||
* Checks whether a drawable with a resoure id is grayscale. Grayscale here means "very close to a
|
||||
* perfect gray".
|
||||
*
|
||||
* @param context The context to load the drawable from.
|
||||
* @return Whether the drawable is grayscale.
|
||||
*/
|
||||
public boolean isGrayscale(Context context, int drawableResId) {
|
||||
if (drawableResId != 0) {
|
||||
try {
|
||||
return isGrayscale(context.getDrawable(drawableResId));
|
||||
} catch (Resources.NotFoundException ex) {
|
||||
Log.e(TAG, "Drawable not found: " + drawableResId);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts all the grayscale colors set by {@link android.text.style.TextAppearanceSpan}s on the
|
||||
* text.
|
||||
*
|
||||
* @param charSequence The text to process.
|
||||
* @return The color inverted text.
|
||||
*/
|
||||
/**
|
||||
* Inverts all the grayscale colors set by {@link android.text.style.TextAppearanceSpan}s on the
|
||||
* text.
|
||||
*
|
||||
* @param charSequence The text to process.
|
||||
* @return The color inverted text.
|
||||
*/
|
||||
|
||||
|
||||
private int processColor(int color) {
|
||||
return Color.argb(Color.alpha(color),
|
||||
255 - Color.red(color),
|
||||
255 - Color.green(color),
|
||||
255 - Color.blue(color));
|
||||
}
|
||||
private int processColor(int color) {
|
||||
return Color.argb(Color.alpha(color),
|
||||
255 - Color.red(color),
|
||||
255 - Color.green(color),
|
||||
255 - Color.blue(color));
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import io.reactivex.schedulers.Schedulers;
|
|||
|
||||
public class SchedulerProvider implements BaseSchedulerProvider {
|
||||
@NonNull
|
||||
private static SchedulerProvider INSTANCE ;
|
||||
private static SchedulerProvider INSTANCE;
|
||||
|
||||
public SchedulerProvider() {
|
||||
}
|
||||
|
|
|
@ -908,7 +908,7 @@ public class BottomNavigationViewEx extends BottomNavigationView {
|
|||
}
|
||||
|
||||
public void enableShiftingMode(int position, boolean enable) {
|
||||
getBottomNavigationItemView(position).setShiftingMode(enable);
|
||||
//getBottomNavigationItemView(position).setShiftingMode(enable);
|
||||
}
|
||||
|
||||
public void setItemBackground(int position, int background) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.MediaRouteButton;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ContextThemeWrapper;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
public class CustomMediaRouteButton extends MediaRouteButton {
|
||||
|
||||
@Nullable
|
||||
private Activity activity;
|
||||
|
||||
public CustomMediaRouteButton(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CustomMediaRouteButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.mediaRouteButtonStyle);
|
||||
}
|
||||
|
||||
public CustomMediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(getThemedContext(context), attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private static Context getThemedContext(Context context) {
|
||||
return ATHUtil.isWindowBackgroundDark(context) ?
|
||||
new ContextThemeWrapper(new ContextThemeWrapper(context, R.style.Theme_AppCompat), R.style.Theme_MediaRouter) :
|
||||
new ContextThemeWrapper(new ContextThemeWrapper(context, R.style.Theme_AppCompat_Light), R.style.Theme_MediaRouter);
|
||||
}
|
||||
|
||||
public void setActivity(@NonNull Activity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showDialog() {
|
||||
|
||||
if (!RetroApplication.isProVersion()) {
|
||||
if (activity != null) {
|
||||
NavigationUtil.goToProVersion((Activity) getContext());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.showDialog();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package code.name.monkey.retromusic.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
import android.support.v7.app.MediaRouteActionProvider;
|
||||
import android.support.v7.app.MediaRouteButton;
|
||||
import android.support.v7.view.ContextThemeWrapper;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
|
||||
public class ThemeableMediaRouteActionProvider extends MediaRouteActionProvider {
|
||||
public ThemeableMediaRouteActionProvider(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaRouteButton onCreateMediaRouteButton() {
|
||||
MediaRouteButton button = super.onCreateMediaRouteButton();
|
||||
colorWorkaroundForCastIcon(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaRouteButton getMediaRouteButton() {
|
||||
MediaRouteButton button = super.getMediaRouteButton();
|
||||
colorWorkaroundForCastIcon(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
private void colorWorkaroundForCastIcon(MediaRouteButton button) {
|
||||
if (button == null) return;
|
||||
Context castContext = new ContextThemeWrapper(getContext(), android.support.v7.mediarouter.R.style.Theme_MediaRouter);
|
||||
|
||||
TypedArray a = castContext.obtainStyledAttributes(null,
|
||||
android.support.v7.mediarouter.R.styleable.MediaRouteButton, android.support.v7.mediarouter.R.attr.mediaRouteButtonStyle, 0);
|
||||
Drawable drawable = a.getDrawable(
|
||||
android.support.v7.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable);
|
||||
a.recycle();
|
||||
if (drawable != null) {
|
||||
DrawableCompat.setTint(drawable, ThemeStore.textColorPrimary(getContext()));
|
||||
drawable.setState(button.getDrawableState());
|
||||
button.setRemoteIndicatorDrawable(drawable);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue