From 4aa0ccc28319b0dd8da748027f1923e972b1930d Mon Sep 17 00:00:00 2001 From: h4h13 Date: Sun, 5 Aug 2018 22:05:59 +0530 Subject: [PATCH] code refactor --- .idea/RetroMusicPlayer.iml | 19 - .idea/assetWizardSettings.xml | 14 + ..._libs_jsoup_1_11_2_jar_unspecified_jar.xml | 9 - .../Gradle__com_mpatric_mp3agic_0_8_3_jar.xml | 11 - ...p_wasabeef_glide_transformations_2_0_2.xml | 14 - .idea/misc.xml | 13 +- .idea/modules.xml | 2 +- .idea/vcs.xml | 1 - RetroMusicPlayer.iml | 2 +- app/app.iml | 9 +- app/build.gradle | 4 +- .../name/monkey/retromusic/Injection.java | 18 +- .../retromusic/swipebtn/DimentionUtils.java | 13 - .../retromusic/swipebtn/OnActiveListener.java | 5 - .../swipebtn/OnStateChangeListener.java | 5 - .../retromusic/swipebtn/SwipeButton.java | 486 ----------- .../retromusic/swipebtn/TouchUtils.java | 13 - .../ui/activities/base/AbsThemeActivity.java | 3 - ...gerRecyclerViewCustomGridSizeFragment.java | 2 +- .../AbsLibraryPagerRecyclerViewFragment.java | 225 +++-- .../mainactivity/AlbumsFragment.java | 246 +++--- .../mainactivity/ArtistsFragment.java | 280 +++--- .../fragments/mainactivity/GenreFragment.java | 4 +- .../mainactivity/LibraryFragment.java | 803 +++++++++--------- .../mainactivity/PlaylistsFragment.java | 4 +- .../fragments/mainactivity/SongsFragment.java | 281 +++--- .../mainactivity/folders/FoldersFragment.java | 25 +- .../mainactivity/home/HomeFragment.java | 687 +++++++-------- .../plain/PlainPlaybackControlsFragment.java | 546 ++++++------ .../SimplePlaybackControlsFragment.java | 541 ++++++------ appthemehelper/appthemehelper.iml | 7 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 54708 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 100 ++- gradlew.bat | 14 +- public.properties | 5 - 37 files changed, 1939 insertions(+), 2476 deletions(-) delete mode 100644 .idea/RetroMusicPlayer.iml create mode 100644 .idea/assetWizardSettings.xml delete mode 100644 .idea/libraries/Gradle____local_aars____Users_hemanths_Desktop_KeepSafe_RetroMusicPlayer_app_libs_jsoup_1_11_2_jar_unspecified_jar.xml delete mode 100644 .idea/libraries/Gradle__com_mpatric_mp3agic_0_8_3_jar.xml delete mode 100644 .idea/libraries/Gradle__jp_wasabeef_glide_transformations_2_0_2.xml delete mode 100755 app/src/main/java/code/name/monkey/retromusic/swipebtn/DimentionUtils.java delete mode 100755 app/src/main/java/code/name/monkey/retromusic/swipebtn/OnActiveListener.java delete mode 100755 app/src/main/java/code/name/monkey/retromusic/swipebtn/OnStateChangeListener.java delete mode 100755 app/src/main/java/code/name/monkey/retromusic/swipebtn/SwipeButton.java delete mode 100755 app/src/main/java/code/name/monkey/retromusic/swipebtn/TouchUtils.java delete mode 100755 public.properties diff --git a/.idea/RetroMusicPlayer.iml b/.idea/RetroMusicPlayer.iml deleted file mode 100644 index c5796822..00000000 --- a/.idea/RetroMusicPlayer.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 00000000..2a9c5e01 --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle____local_aars____Users_hemanths_Desktop_KeepSafe_RetroMusicPlayer_app_libs_jsoup_1_11_2_jar_unspecified_jar.xml b/.idea/libraries/Gradle____local_aars____Users_hemanths_Desktop_KeepSafe_RetroMusicPlayer_app_libs_jsoup_1_11_2_jar_unspecified_jar.xml deleted file mode 100644 index c6d6bce5..00000000 --- a/.idea/libraries/Gradle____local_aars____Users_hemanths_Desktop_KeepSafe_RetroMusicPlayer_app_libs_jsoup_1_11_2_jar_unspecified_jar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_mpatric_mp3agic_0_8_3_jar.xml b/.idea/libraries/Gradle__com_mpatric_mp3agic_0_8_3_jar.xml deleted file mode 100644 index 9b5bf4b0..00000000 --- a/.idea/libraries/Gradle__com_mpatric_mp3agic_0_8_3_jar.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__jp_wasabeef_glide_transformations_2_0_2.xml b/.idea/libraries/Gradle__jp_wasabeef_glide_transformations_2_0_2.xml deleted file mode 100644 index 24015588..00000000 --- a/.idea/libraries/Gradle__jp_wasabeef_glide_transformations_2_0_2.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 26dc4f51..ddffd329 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,25 +5,32 @@ - + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index bef72af7..9138ca8d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 83067447..35eb1ddf 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,5 @@ - \ No newline at end of file diff --git a/RetroMusicPlayer.iml b/RetroMusicPlayer.iml index c5796822..92f9a14a 100644 --- a/RetroMusicPlayer.iml +++ b/RetroMusicPlayer.iml @@ -13,7 +13,7 @@ - + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index cf066c09..be879509 100644 --- a/app/app.iml +++ b/app/app.iml @@ -130,6 +130,8 @@ + + @@ -141,11 +143,16 @@ + + + + + @@ -159,7 +166,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 930f5a87..bc3183e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" - versionCode 206 - versionName 'R - 1.7.10' + versionCode 207 + versionName '1.7.10' multiDexEnabled true diff --git a/app/src/main/java/code/name/monkey/retromusic/Injection.java b/app/src/main/java/code/name/monkey/retromusic/Injection.java index 481613ff..4fe94a74 100644 --- a/app/src/main/java/code/name/monkey/retromusic/Injection.java +++ b/app/src/main/java/code/name/monkey/retromusic/Injection.java @@ -9,15 +9,15 @@ import code.name.monkey.retromusic.util.schedulers.SchedulerProvider; public class Injection { - public static Repository provideRepository() { - return RepositoryImpl.getInstance(); - } + public static Repository provideRepository() { + return RepositoryImpl.getInstance(); + } - public static BaseSchedulerProvider provideSchedulerProvider() { - return SchedulerProvider.getInstance(); - } + public static BaseSchedulerProvider provideSchedulerProvider() { + return SchedulerProvider.getInstance(); + } - public static KuGouApiService provideKuGouApiService() { - return new KogouClient().getApiService(); - } + public static KuGouApiService provideKuGouApiService() { + return new KogouClient().getApiService(); + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/swipebtn/DimentionUtils.java b/app/src/main/java/code/name/monkey/retromusic/swipebtn/DimentionUtils.java deleted file mode 100755 index 587055a5..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/swipebtn/DimentionUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package code.name.monkey.retromusic.swipebtn; - -import android.content.Context; - -final class DimentionUtils { - - private DimentionUtils() { - } - - static float convertPixelsToSp(float px, Context context) { - return px / context.getResources().getDisplayMetrics().scaledDensity; - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnActiveListener.java b/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnActiveListener.java deleted file mode 100755 index 429584ce..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnActiveListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package code.name.monkey.retromusic.swipebtn; - -public interface OnActiveListener { - void onActive(); -} diff --git a/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnStateChangeListener.java b/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnStateChangeListener.java deleted file mode 100755 index c4adf4a2..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/swipebtn/OnStateChangeListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package code.name.monkey.retromusic.swipebtn; - -public interface OnStateChangeListener { - void onStateChange(boolean active); -} diff --git a/app/src/main/java/code/name/monkey/retromusic/swipebtn/SwipeButton.java b/app/src/main/java/code/name/monkey/retromusic/swipebtn/SwipeButton.java deleted file mode 100755 index eaecc952..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/swipebtn/SwipeButton.java +++ /dev/null @@ -1,486 +0,0 @@ -package code.name.monkey.retromusic.swipebtn; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import code.name.monkey.retromusic.R; - -public class SwipeButton extends RelativeLayout { - - - private static final int ENABLED = 0; - private static final int DISABLED = 1; - private ImageView swipeButtonInner; - private float initialX; - private boolean active; - private TextView centerText; - private ViewGroup background; - private Drawable disabledDrawable; - private Drawable enabledDrawable; - private OnStateChangeListener onStateChangeListener; - private OnActiveListener onActiveListener; - private int collapsedWidth; - private int collapsedHeight; - - private LinearLayout layer; - private boolean trailEnabled = false; - private boolean hasActivationState; - - public SwipeButton(Context context) { - super(context); - - init(context, null, -1, -1); - } - - public SwipeButton(Context context, AttributeSet attrs) { - super(context, attrs); - - init(context, attrs, -1, -1); - } - - public SwipeButton(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - init(context, attrs, defStyleAttr, -1); - } - - @TargetApi(21) - public SwipeButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - - init(context, attrs, defStyleAttr, defStyleRes); - } - - public void setCenterTextColor(int color) { - if (centerText == null) { - return; - } - centerText.setTextColor(color); - } - - public boolean isActive() { - return active; - } - - public void setText(String text) { - centerText.setText(text); - } - - public void setBackground(Drawable drawable) { - background.setBackground(drawable); - } - - public ViewGroup getSwipeBackground() { - return background; - } - - public void setSlidingButtonBackground(Drawable drawable) { - background.setBackground(drawable); - } - - public void setDisabledDrawable(Drawable drawable) { - disabledDrawable = drawable; - - if (!active) { - swipeButtonInner.setImageDrawable(drawable); - } - } - - public void setButtonBackground(Drawable buttonBackground) { - if (buttonBackground != null) { - swipeButtonInner.setBackground(buttonBackground); - } - } - - public void setEnabledDrawable(Drawable drawable) { - enabledDrawable = drawable; - - if (active) { - swipeButtonInner.setImageDrawable(drawable); - } - } - - public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) { - this.onStateChangeListener = onStateChangeListener; - } - - public void setOnActiveListener(OnActiveListener onActiveListener) { - this.onActiveListener = onActiveListener; - } - - public void setInnerTextPadding(int left, int top, int right, int bottom) { - centerText.setPadding(left, top, right, bottom); - } - - public void setSwipeButtonPadding(int left, int top, int right, int bottom) { - swipeButtonInner.setPadding(left, top, right, bottom); - } - - public void setHasActivationState(boolean hasActivationState) { - this.hasActivationState = hasActivationState; - } - - private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - hasActivationState = true; - - background = new RelativeLayout(context); - - LayoutParams layoutParamsView = new LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - layoutParamsView.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); - - addView(background, layoutParamsView); - - final TextView centerText = new TextView(context); - this.centerText = centerText; - centerText.setGravity(Gravity.CENTER); - - LayoutParams layoutParams = new LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); - - background.addView(centerText, layoutParams); - - final ImageView swipeButton = new ImageView(context); - this.swipeButtonInner = swipeButton; - - if (attrs != null && defStyleAttr == -1 && defStyleRes == -1) { - TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SwipeButton, - defStyleAttr, defStyleRes); - - collapsedWidth = (int) typedArray.getDimension(R.styleable.SwipeButton_button_image_width, - ViewGroup.LayoutParams.WRAP_CONTENT); - collapsedHeight = (int) typedArray.getDimension(R.styleable.SwipeButton_button_image_height, - ViewGroup.LayoutParams.WRAP_CONTENT); - trailEnabled = typedArray.getBoolean(R.styleable.SwipeButton_button_trail_enabled, - false); - Drawable trailingDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_trail_drawable); - - Drawable backgroundDrawable = typedArray.getDrawable(R.styleable.SwipeButton_inner_text_background); - - if (backgroundDrawable != null) { - background.setBackground(backgroundDrawable); - } else { - background.setBackground(ContextCompat.getDrawable(context, R.drawable.shape_rounded_edit)); - } - - if (trailEnabled) { - layer = new LinearLayout(context); - - if (trailingDrawable != null) { - layer.setBackground(trailingDrawable); - } else { - layer.setBackground(typedArray.getDrawable(R.styleable.SwipeButton_button_background)); - } - - layer.setGravity(Gravity.START); - layer.setVisibility(View.GONE); - background.addView(layer, layoutParamsView); - } - - centerText.setText(typedArray.getText(R.styleable.SwipeButton_inner_text)); - centerText.setTextColor(typedArray.getColor(R.styleable.SwipeButton_inner_text_color, - Color.WHITE)); - - float textSize = DimentionUtils.convertPixelsToSp( - typedArray.getDimension(R.styleable.SwipeButton_inner_text_size, 0), context); - - if (textSize != 0) { - centerText.setTextSize(textSize); - } else { - centerText.setTextSize(12); - } - - disabledDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_image_disabled); - enabledDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_image_enabled); - float innerTextLeftPadding = typedArray.getDimension( - R.styleable.SwipeButton_inner_text_left_padding, 0); - float innerTextTopPadding = typedArray.getDimension( - R.styleable.SwipeButton_inner_text_top_padding, 0); - float innerTextRightPadding = typedArray.getDimension( - R.styleable.SwipeButton_inner_text_right_padding, 0); - float innerTextBottomPadding = typedArray.getDimension( - R.styleable.SwipeButton_inner_text_bottom_padding, 0); - - int initialState = typedArray.getInt(R.styleable.SwipeButton_initial_state, DISABLED); - - if (initialState == ENABLED) { - LayoutParams layoutParamsButton = new LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - layoutParamsButton.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE); - layoutParamsButton.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE); - - swipeButton.setImageDrawable(enabledDrawable); - - addView(swipeButton, layoutParamsButton); - - active = true; - } else { - LayoutParams layoutParamsButton = new LayoutParams(collapsedWidth, collapsedHeight); - - layoutParamsButton.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE); - layoutParamsButton.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE); - - swipeButton.setImageDrawable(disabledDrawable); - - addView(swipeButton, layoutParamsButton); - - active = false; - } - - centerText.setPadding((int) innerTextLeftPadding, - (int) innerTextTopPadding, - (int) innerTextRightPadding, - (int) innerTextBottomPadding); - - Drawable buttonBackground = typedArray.getDrawable(R.styleable.SwipeButton_button_background); - - if (buttonBackground != null) { - swipeButton.setBackground(buttonBackground); - } else { - swipeButton.setBackground(ContextCompat.getDrawable(context, R.drawable.shape_rounded_edit)); - } - - float buttonLeftPadding = typedArray.getDimension( - R.styleable.SwipeButton_button_left_padding, 0); - float buttonTopPadding = typedArray.getDimension( - R.styleable.SwipeButton_button_top_padding, 0); - float buttonRightPadding = typedArray.getDimension( - R.styleable.SwipeButton_button_right_padding, 0); - float buttonBottomPadding = typedArray.getDimension( - R.styleable.SwipeButton_button_bottom_padding, 0); - - swipeButton.setPadding((int) buttonLeftPadding, - (int) buttonTopPadding, - (int) buttonRightPadding, - (int) buttonBottomPadding); - - hasActivationState = typedArray.getBoolean(R.styleable.SwipeButton_has_activate_state, true); - - typedArray.recycle(); - } - - setOnTouchListener(getButtonTouchListener()); - } - - private OnTouchListener getButtonTouchListener() { - return new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - return !TouchUtils.isTouchOutsideInitialPosition(event, swipeButtonInner); - case MotionEvent.ACTION_MOVE: - if (initialX == 0) { - initialX = swipeButtonInner.getX(); - } - - if (event.getX() > swipeButtonInner.getWidth() / 2 && - event.getX() + swipeButtonInner.getWidth() / 2 < getWidth()) { - swipeButtonInner.setX(event.getX() - swipeButtonInner.getWidth() / 2); - centerText.setAlpha(1 - 1.3f * (swipeButtonInner.getX() + swipeButtonInner.getWidth()) / getWidth()); - setTrailingEffect(); - } - - if (event.getX() + swipeButtonInner.getWidth() / 2 > getWidth() && - swipeButtonInner.getX() + swipeButtonInner.getWidth() / 2 < getWidth()) { - swipeButtonInner.setX(getWidth() - swipeButtonInner.getWidth()); - } - - if (event.getX() < swipeButtonInner.getWidth() / 2) { - swipeButtonInner.setX(0); - } - - return true; - case MotionEvent.ACTION_UP: - if (active) { - collapseButton(); - } else { - if (swipeButtonInner.getX() + swipeButtonInner.getWidth() > getWidth() * 0.9) { - if (hasActivationState) { - expandButton(); - } else if (onActiveListener != null) { - onActiveListener.onActive(); - moveButtonBack(); - } - } else { - moveButtonBack(); - } - } - - return true; - } - - return false; - } - }; - } - - private void expandButton() { - final ValueAnimator positionAnimator = - ValueAnimator.ofFloat(swipeButtonInner.getX(), 0); - positionAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float x = (Float) positionAnimator.getAnimatedValue(); - swipeButtonInner.setX(x); - } - }); - - - final ValueAnimator widthAnimator = ValueAnimator.ofInt( - swipeButtonInner.getWidth(), - getWidth()); - - widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - ViewGroup.LayoutParams params = swipeButtonInner.getLayoutParams(); - params.width = (Integer) widthAnimator.getAnimatedValue(); - swipeButtonInner.setLayoutParams(params); - } - }); - - - AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - - active = true; - swipeButtonInner.setImageDrawable(enabledDrawable); - - if (onStateChangeListener != null) { - onStateChangeListener.onStateChange(active); - } - - if (onActiveListener != null) { - onActiveListener.onActive(); - } - } - }); - - animatorSet.playTogether(positionAnimator, widthAnimator); - animatorSet.start(); - } - - private void moveButtonBack() { - final ValueAnimator positionAnimator = - ValueAnimator.ofFloat(swipeButtonInner.getX(), 0); - positionAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); - positionAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float x = (Float) positionAnimator.getAnimatedValue(); - swipeButtonInner.setX(x); - setTrailingEffect(); - } - }); - - positionAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - if (layer != null) { - layer.setVisibility(View.GONE); - } - } - }); - - ObjectAnimator objectAnimator = ObjectAnimator.ofFloat( - centerText, "alpha", 1); - - positionAnimator.setDuration(200); - - AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether(objectAnimator, positionAnimator); - animatorSet.start(); - } - - private void collapseButton() { - int finalWidth; - - if (collapsedWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { - finalWidth = swipeButtonInner.getHeight(); - } else { - finalWidth = collapsedWidth; - } - - final ValueAnimator widthAnimator = ValueAnimator.ofInt(swipeButtonInner.getWidth(), finalWidth); - - widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - ViewGroup.LayoutParams params = swipeButtonInner.getLayoutParams(); - params.width = (Integer) widthAnimator.getAnimatedValue(); - swipeButtonInner.setLayoutParams(params); - setTrailingEffect(); - } - }); - - widthAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - active = false; - swipeButtonInner.setImageDrawable(disabledDrawable); - if (onStateChangeListener != null) { - onStateChangeListener.onStateChange(active); - } - if (layer != null) { - layer.setVisibility(View.GONE); - } - } - }); - - ObjectAnimator objectAnimator = ObjectAnimator.ofFloat( - centerText, "alpha", 1); - - AnimatorSet animatorSet = new AnimatorSet(); - - animatorSet.playTogether(objectAnimator, widthAnimator); - animatorSet.start(); - } - - private void setTrailingEffect() { - if (trailEnabled) { - layer.setVisibility(View.VISIBLE); - layer.setLayoutParams(new LayoutParams( - (int) (swipeButtonInner.getX() + swipeButtonInner.getWidth() / 3), centerText.getHeight())); - } - } - - public void toggleState() { - if (isActive()) { - collapseButton(); - } else { - expandButton(); - } - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/swipebtn/TouchUtils.java b/app/src/main/java/code/name/monkey/retromusic/swipebtn/TouchUtils.java deleted file mode 100755 index b9762592..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/swipebtn/TouchUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package code.name.monkey.retromusic.swipebtn; - -import android.view.MotionEvent; -import android.view.View; - -final class TouchUtils { - private TouchUtils() { - } - - static boolean isTouchOutsideInitialPosition(MotionEvent event, View view) { - return event.getX() > view.getX() + view.getWidth(); - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.java index 7fe40e3e..936317f3 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.java @@ -77,9 +77,6 @@ public abstract class AbsThemeActivity extends ATHToolbarActivity implements Run : ContextCompat.getDrawable(this, R.drawable.square_window); background = TintHelper.createTintedDrawable(background, ThemeStore.primaryColor(this)); getWindow().setBackgroundDrawable(background); - //View decor = getWindow().getDecorView(); - //GradientDrawable gradientDrawable = (GradientDrawable) decor.getBackground(); - //gradientDrawable.setColor(ThemeStore.primaryColor(this)); } protected void setDrawUnderStatusBar(boolean drawUnderStatusbar) { diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.java index 16f999ef..a4ee752a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.java @@ -120,7 +120,7 @@ public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment 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 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())); } + recyclerView.setLayoutManager(layoutManager); + recyclerView.setAdapter(adapter); + } - @Override - public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - getLibraryFragment().addOnAppBarOffsetChangedListener(this); - initLayoutManager(); - initAdapter(); - setUpRecyclerView(); - } + @Override + public void onQueueChanged() { + super.onQueueChanged(); + checkForPadding(); + } - private void setUpRecyclerView() { - if (recyclerView instanceof FastScrollRecyclerView) { - //noinspection ConstantConditions - ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), - ((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity())); - } - recyclerView.setLayoutManager(layoutManager); - recyclerView.setAdapter(adapter); - } + @Override + public void onServiceConnected() { + super.onServiceConnected(); + checkForPadding(); + } - @Override - public void onQueueChanged() { - super.onQueueChanged(); - checkForPadding(); - } + private void checkForPadding() { + int height = (MusicPlayerRemote.getPlayingQueue().isEmpty() ? getResources() + .getDimensionPixelSize(R.dimen.mini_player_height) : 0); + recyclerView.setPadding(0, 0, 0, height); + } - @Override - public void onServiceConnected() { - super.onServiceConnected(); - checkForPadding(); - } + protected void invalidateLayoutManager() { + initLayoutManager(); + recyclerView.setLayoutManager(layoutManager); + } - private void checkForPadding() { - int height = (MusicPlayerRemote.getPlayingQueue().isEmpty() ? getResources().getDimensionPixelSize(R.dimen.mini_player_height) : 0); - recyclerView.setPadding(0, 0, 0, height); - } + protected void invalidateAdapter() { + initAdapter(); + checkIsEmpty(); + recyclerView.setAdapter(adapter); + } - protected void invalidateLayoutManager() { - initLayoutManager(); - recyclerView.setLayoutManager(layoutManager); - } - - protected void invalidateAdapter() { - initAdapter(); + private void initAdapter() { + adapter = createAdapter(); + adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { + @Override + public void onChanged() { + super.onChanged(); checkIsEmpty(); - recyclerView.setAdapter(adapter); - } + checkForPadding(); + } + }); + } - private void initAdapter() { - adapter = createAdapter(); - adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - @Override - public void onChanged() { - super.onChanged(); - checkIsEmpty(); - checkForPadding(); - } - }); - } + private void initLayoutManager() { + layoutManager = createLayoutManager(); + } - private void initLayoutManager() { - layoutManager = createLayoutManager(); - } + protected A getAdapter() { + return adapter; + } - protected A getAdapter() { - return adapter; - } + protected LM getLayoutManager() { + return layoutManager; + } - protected LM getLayoutManager() { - return layoutManager; - } + protected RecyclerView getRecyclerView() { + return recyclerView; + } - protected RecyclerView getRecyclerView() { - return recyclerView; - } + public ViewGroup getContainer() { + return container; + } - public ViewGroup getContainer() { - return container; - } + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int i) { + container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), + container.getPaddingRight(), getLibraryFragment().getTotalAppBarScrollingRange() + i); + } - @Override - public void onOffsetChanged(AppBarLayout appBarLayout, int i) { - container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), - container.getPaddingRight(), getLibraryFragment().getTotalAppBarScrollingRange() + i); - } + private void checkIsEmpty() { + empty.setText(getEmptyMessage()); + empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); + } - 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; + } - @StringRes - protected int getEmptyMessage() { - return R.string.empty; - } + @LayoutRes + protected int getLayoutRes() { + return R.layout.fragment_main_activity_recycler_view; + } - @LayoutRes - protected int getLayoutRes() { - return R.layout.fragment_main_activity_recycler_view; - } + protected abstract LM createLayoutManager(); - protected abstract LM createLayoutManager(); + @NonNull + protected abstract A createAdapter(); - @NonNull - protected abstract A createAdapter(); - - @Override - public void onDestroyView() { - super.onDestroyView(); - getLibraryFragment().removeOnAppBarOffsetChangedListener(this); - unbinder.unbind(); - } + @Override + public void onDestroyView() { + super.onDestroyView(); + getLibraryFragment().removeOnAppBarOffsetChangedListener(this); + unbinder.unbind(); + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/AlbumsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/AlbumsFragment.java index ccdf51f4..46f6fbc8 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/AlbumsFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/AlbumsFragment.java @@ -4,9 +4,6 @@ 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.Album; import code.name.monkey.retromusic.mvp.contract.AlbumContract; @@ -14,155 +11,156 @@ import code.name.monkey.retromusic.mvp.presenter.AlbumPresenter; import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter; import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment; import code.name.monkey.retromusic.util.PreferenceUtil; +import java.util.ArrayList; public class AlbumsFragment extends - AbsLibraryPagerRecyclerViewCustomGridSizeFragment implements - AlbumContract.AlbumView { + AbsLibraryPagerRecyclerViewCustomGridSizeFragment implements + AlbumContract.AlbumView { - public static final String TAG = AlbumsFragment.class.getSimpleName(); + public static final String TAG = AlbumsFragment.class.getSimpleName(); - private AlbumPresenter presenter; + private AlbumPresenter presenter; - public static AlbumsFragment newInstance() { - Bundle args = new Bundle(); - AlbumsFragment fragment = new AlbumsFragment(); - fragment.setArguments(args); - return fragment; + public static AlbumsFragment newInstance() { + Bundle args = new Bundle(); + AlbumsFragment fragment = new AlbumsFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected GridLayoutManager createLayoutManager() { + return new GridLayoutManager(getActivity(), getGridSize()); + } + + @NonNull + @Override + protected AlbumAdapter createAdapter() { + int itemLayoutRes = getItemLayoutRes(); + notifyLayoutResChanged(itemLayoutRes); + if (itemLayoutRes != R.layout.item_list) { + itemLayoutRes = PreferenceUtil.getInstance(getContext()).getAlbumGridStyle(getContext()); } + ArrayList dataSet = + getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet(); + return new AlbumAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, + loadUsePalette(), getLibraryFragment()); + } - @Override - protected GridLayoutManager createLayoutManager() { - return new GridLayoutManager(getActivity(), getGridSize()); - } + @Override + protected int getEmptyMessage() { + return R.string.no_albums; + } - @NonNull - @Override - protected AlbumAdapter createAdapter() { - int itemLayoutRes = getItemLayoutRes(); - notifyLayoutResChanged(itemLayoutRes); - if (itemLayoutRes != R.layout.item_list) { - itemLayoutRes = PreferenceUtil.getInstance(getContext()).getAlbumGridStyle(getContext()); - } - ArrayList dataSet = - getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet(); - return new AlbumAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, - loadUsePalette(), getLibraryFragment()); - } + @Override + public boolean loadUsePalette() { + return PreferenceUtil.getInstance(getActivity()).albumColoredFooters(); + } - @Override - protected int getEmptyMessage() { - return R.string.no_albums; - } + @Override + protected void setUsePalette(boolean usePalette) { + getAdapter().usePalette(usePalette); + } - @Override - public boolean loadUsePalette() { - return PreferenceUtil.getInstance(getActivity()).albumColoredFooters(); - } + @Override + protected void setGridSize(int gridSize) { + getLayoutManager().setSpanCount(gridSize); + getAdapter().notifyDataSetChanged(); + } - @Override - protected void setUsePalette(boolean usePalette) { - getAdapter().usePalette(usePalette); - } + @Override + protected void setSortOrder(String sortOrder) { + presenter.loadAlbums(); + } - @Override - protected void setGridSize(int gridSize) { - getLayoutManager().setSpanCount(gridSize); - getAdapter().notifyDataSetChanged(); - } + @Override + protected String loadSortOrder() { + return PreferenceUtil.getInstance(getActivity()).getAlbumSortOrder(); + } - @Override - protected void setSortOrder(String sortOrder) { - presenter.loadAlbums(); - } + @Override + protected void saveSortOrder(String sortOrder) { + PreferenceUtil.getInstance(getActivity()).setAlbumSortOrder(sortOrder); + } - @Override - protected String loadSortOrder() { - return PreferenceUtil.getInstance(getActivity()).getAlbumSortOrder(); - } + @Override + protected int loadGridSize() { + return PreferenceUtil.getInstance(getActivity()).getAlbumGridSize(getActivity()); + } - @Override - protected void saveSortOrder(String sortOrder) { - PreferenceUtil.getInstance(getActivity()).setAlbumSortOrder(sortOrder); - } + @Override + protected void saveGridSize(int gridSize) { + PreferenceUtil.getInstance(getActivity()).setAlbumGridSize(gridSize); + } - @Override - protected int loadGridSize() { - return PreferenceUtil.getInstance(getActivity()).getAlbumGridSize(getActivity()); - } + @Override + protected int loadGridSizeLand() { + return PreferenceUtil.getInstance(getActivity()).getAlbumGridSizeLand(getActivity()); + } - @Override - protected void saveGridSize(int gridSize) { - PreferenceUtil.getInstance(getActivity()).setAlbumGridSize(gridSize); - } + @Override + protected void saveGridSizeLand(int gridSize) { + PreferenceUtil.getInstance(getActivity()).setAlbumGridSizeLand(gridSize); + } - @Override - protected int loadGridSizeLand() { - return PreferenceUtil.getInstance(getActivity()).getAlbumGridSizeLand(getActivity()); - } + @Override + protected void saveUsePalette(boolean usePalette) { + PreferenceUtil.getInstance(getActivity()).setAlbumColoredFooters(usePalette); + } - @Override - protected void saveGridSizeLand(int gridSize) { - PreferenceUtil.getInstance(getActivity()).setAlbumGridSizeLand(gridSize); - } + @Override + public void onMediaStoreChanged() { + presenter.loadAlbums(); + } - @Override - protected void saveUsePalette(boolean usePalette) { - PreferenceUtil.getInstance(getActivity()).setAlbumColoredFooters(usePalette); - } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + presenter = new AlbumPresenter(this); + } - @Override - public void onMediaStoreChanged() { - presenter.loadAlbums(); + @Override + public void setMenuVisibility(boolean menuVisible) { + super.setMenuVisibility(menuVisible); + if (menuVisible) { + getLibraryFragment().setTitle( + PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library + : R.string.albums); } + } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - presenter = new AlbumPresenter(this); + @Override + public void onResume() { + super.onResume(); + getLibraryFragment().setTitle( + PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.albums); + if (getAdapter().getDataSet().isEmpty()) { + presenter.subscribe(); } + } - @Override - public void setMenuVisibility(boolean menuVisible) { - super.setMenuVisibility(menuVisible); - if (menuVisible) { - getLibraryFragment().getToolbar().setTitle( - PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library - : R.string.albums); - } - } + @Override + public void onDestroy() { + super.onDestroy(); + presenter.unsubscribe(); + } - @Override - public void onResume() { - super.onResume(); - getLibraryFragment().getToolbar().setTitle( - PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.albums); - if (getAdapter().getDataSet().isEmpty()) { - presenter.subscribe(); - } - } + @Override + public void loading() { + } - @Override - public void onDestroy() { - super.onDestroy(); - presenter.unsubscribe(); - } + @Override + public void showEmptyView() { + getAdapter().swapDataSet(new ArrayList<>()); + } - @Override - public void loading() { - } + @Override + public void completed() { + } - @Override - public void showEmptyView() { - getAdapter().swapDataSet(new ArrayList<>()); - } - - @Override - public void completed() { - } - - @Override - public void showData(ArrayList albums) { - getAdapter().swapDataSet(albums); - } + @Override + public void showData(ArrayList albums) { + getAdapter().swapDataSet(albums); + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/ArtistsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/ArtistsFragment.java index 82069802..86554410 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/ArtistsFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/ArtistsFragment.java @@ -4,9 +4,6 @@ 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; @@ -14,160 +11,161 @@ 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 implements - ArtistContract.ArtistView { + AbsLibraryPagerRecyclerViewCustomGridSizeFragment 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; + 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()); } + ArrayList dataSet = + getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet(); + return new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, + loadUsePalette(), getLibraryFragment()); + } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - presenter = new ArtistPresenter(this); + @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); } + } - @NonNull - @Override - protected GridLayoutManager createLayoutManager() { - return new GridLayoutManager(getActivity(), getGridSize()); + @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 ArtistAdapter createAdapter() { - int itemLayoutRes = getItemLayoutRes(); - notifyLayoutResChanged(itemLayoutRes); - if (itemLayoutRes != R.layout.item_list) { - itemLayoutRes = PreferenceUtil.getInstance(getContext()).getArtistGridStyle(getContext()); - } - ArrayList dataSet = - getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet(); - return new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, - loadUsePalette(), getLibraryFragment()); - } + @Override + public void onDestroy() { + super.onDestroy(); + presenter.unsubscribe(); + } - @Override - protected int getEmptyMessage() { - return R.string.no_artists; - } + @Override + public void loading() { + } - @Override - public void onMediaStoreChanged() { - presenter.loadArtists(); - } + @Override + public void showEmptyView() { + getAdapter().swapDataSet(new ArrayList<>()); + } - @Override - protected int loadGridSize() { - return PreferenceUtil.getInstance(getActivity()).getArtistGridSize(getActivity()); - } + @Override + public void completed() { - @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().getToolbar().setTitle( - PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library - : R.string.artists); - } - } - - @Override - public void onResume() { - super.onResume(); - getLibraryFragment().getToolbar().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 artists) { - getAdapter().swapDataSet(artists); - } + @Override + public void showData(ArrayList artists) { + getAdapter().swapDataSet(artists); + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.java index 9925b60f..5f973bf1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.java @@ -39,7 +39,7 @@ public class GenreFragment extends public void setMenuVisibility(boolean menuVisible) { super.setMenuVisibility(menuVisible); if (menuVisible) { - getLibraryFragment().getToolbar().setTitle( + getLibraryFragment().setTitle( PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres); } @@ -48,7 +48,7 @@ public class GenreFragment extends @Override public void onResume() { super.onResume(); - getLibraryFragment().getToolbar().setTitle( + getLibraryFragment().setTitle( PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres); if (getAdapter().getDataSet().isEmpty()) { mPresenter.subscribe(); diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.java index 77e94be9..92553498 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.java @@ -5,7 +5,9 @@ import android.content.Intent; 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.CollapsingToolbarLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; @@ -17,11 +19,6 @@ import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.view.ViewGroup; - -import com.afollestad.materialcab.MaterialCab; - -import java.util.Objects; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; @@ -37,422 +34,422 @@ 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.ui.activities.SearchActivity; 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.RetroColorUtil; import code.name.monkey.retromusic.util.RetroUtil; -import code.name.monkey.retromusic.views.SansFontCollapsingToolbarLayout; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; +import com.afollestad.materialcab.MaterialCab; public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, - MainActivityFragmentCallbacks { + MainActivityFragmentCallbacks { - private static final String TAG = "LibraryFragment"; - private static final String CURRENT_TAB_ID = "current_tab_id"; - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.appbar) - AppBarLayout appbar; - @BindView(R.id.collapsing_toolbar) - SansFontCollapsingToolbarLayout collapsingToolbar; + private static final String TAG = "LibraryFragment"; + private static final String CURRENT_TAB_ID = "current_tab_id"; + @BindView(R.id.toolbar) + Toolbar toolbar; + @BindView(R.id.app_bar) + AppBarLayout appbar; + @BindView(R.id.collapsing_toolbar) + CollapsingToolbarLayout collapsingToolbarLayout; - private Unbinder unBinder; - private MaterialCab cab; - private FragmentManager fragmentManager; - public static Fragment newInstance(int tab) { - Bundle args = new Bundle(); - args.putInt(CURRENT_TAB_ID, tab); - LibraryFragment fragment = new LibraryFragment(); - fragment.setArguments(args); - return fragment; + private Unbinder unBinder; + private MaterialCab cab; + private FragmentManager fragmentManager; + + public static Fragment newInstance(int tab) { + Bundle args = new Bundle(); + args.putInt(CURRENT_TAB_ID, tab); + LibraryFragment fragment = new LibraryFragment(); + fragment.setArguments(args); + return fragment; + } + + public void setTitle(@StringRes int name) { + collapsingToolbarLayout.setTitle(getString(name)); + } + + public void addOnAppBarOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { + appbar.addOnOffsetChangedListener(onOffsetChangedListener); + } + + public void removeOnAppBarOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { + appbar.removeOnOffsetChangedListener(onOffsetChangedListener); + } + + public int getTotalAppBarScrollingRange() { + return appbar.getTotalScrollRange(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_library, container, false); + unBinder = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + setStatusbarColorAuto(view); + getMainActivity().setBottomBarVisibility(View.VISIBLE); + setupToolbar(); + + inflateFragment(); + } + + private void inflateFragment() { + if (getArguments() == 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 primaryColor = ThemeStore.primaryColor(getContext()); + appbar.setBackgroundColor(primaryColor); + toolbar.setBackgroundColor(primaryColor); + appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> + getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext()))); + getMainActivity().setTitle(R.string.app_name); + getMainActivity().setSupportActionBar(toolbar); + } + + public Fragment getCurrentFragment() { + if (fragmentManager == null) { + return SongsFragment.newInstance(); + } + return fragmentManager.findFragmentByTag(LibraryFragment.TAG); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + unBinder.unbind(); + } + + @Override + public boolean handleBackPress() { + if (cab != null && cab.isActive()) { + cab.finish(); + return true; + } + return false; + } + + public void selectedFragment(Fragment fragment) { + fragmentManager = getChildFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + + fragmentTransaction + .replace(R.id.fragment_container, fragment, TAG) + .commit(); + } + + @NonNull + @Override + public MaterialCab openCab(int menuRes, MaterialCab.Callback callback) { + if (cab != null && cab.isActive()) { + cab.finish(); + } + //noinspection ConstantConditions + cab = new MaterialCab(getMainActivity(), R.id.cab_stub) + .setMenu(menuRes) + .setCloseDrawableRes(R.drawable.ic_close_white_24dp) + .setBackgroundColor( + RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(getActivity()))) + .start(callback); + return cab; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_main, menu); + + Fragment currentFragment = getCurrentFragment(); + if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment + && currentFragment.isAdded()) { + AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment; + + MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size); + if (RetroUtil.isLandscape(getResources())) { + gridSizeItem.setTitle(R.string.action_grid_size_land); + } + setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu()); + + setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu()); + + } else { + menu.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title); + menu.removeItem(R.id.action_grid_size); + } + Activity activity = getActivity(); + if (activity == null) { + return; + } + ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu, + ATHToolbarActivity.getToolbarBackgroundColor(toolbar)); + } + + private void setUpSortOrderMenu( + @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, + @NonNull SubMenu sortOrderMenu) { + String currentSortOrder = fragment.getSortOrder(); + sortOrderMenu.clear(); + + if (fragment instanceof AlbumsFragment) { + sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z) + .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z)); + sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a) + .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A)); + sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist) + .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST)); + sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year) + .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR)); + } else if (fragment instanceof ArtistsFragment) { + sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z) + .setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z)); + sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a) + .setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A)); + } else if (fragment instanceof SongsFragment) { + sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z)); + sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A)); + sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST)); + sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM)); + sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR)); + sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date) + .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE)); } - public SansFontCollapsingToolbarLayout getToolbar() { - return collapsingToolbar; + sortOrderMenu.setGroupCheckable(0, true, true); + } + + private boolean handleSortOrderMenuItem( + @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) { + String sortOrder = null; + if (fragment instanceof AlbumsFragment) { + switch (item.getItemId()) { + case R.id.action_album_sort_order_asc: + sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z; + break; + case R.id.action_album_sort_order_desc: + sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A; + break; + case R.id.action_album_sort_order_artist: + sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST; + break; + case R.id.action_album_sort_order_year: + sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR; + break; + } + } else if (fragment instanceof ArtistsFragment) { + switch (item.getItemId()) { + case R.id.action_artist_sort_order_asc: + sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z; + break; + case R.id.action_artist_sort_order_desc: + sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A; + break; + } + } else if (fragment instanceof SongsFragment) { + switch (item.getItemId()) { + case R.id.action_song_sort_order_asc: + sortOrder = SortOrder.SongSortOrder.SONG_A_Z; + break; + case R.id.action_song_sort_order_desc: + sortOrder = SortOrder.SongSortOrder.SONG_Z_A; + break; + case R.id.action_song_sort_order_artist: + sortOrder = SortOrder.SongSortOrder.SONG_ARTIST; + break; + case R.id.action_song_sort_order_album: + sortOrder = SortOrder.SongSortOrder.SONG_ALBUM; + break; + case R.id.action_song_sort_order_year: + sortOrder = SortOrder.SongSortOrder.SONG_YEAR; + break; + case R.id.action_song_sort_order_date: + sortOrder = SortOrder.SongSortOrder.SONG_DATE; + break; + } } - public void addOnAppBarOffsetChangedListener( - AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { - appbar.addOnOffsetChangedListener(onOffsetChangedListener); + if (sortOrder != null) { + item.setChecked(true); + fragment.setAndSaveSortOrder(sortOrder); + return true; } - public void removeOnAppBarOffsetChangedListener( - AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { - appbar.removeOnOffsetChangedListener(onOffsetChangedListener); + return false; + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + Activity activity = getActivity(); + if (activity == null) { + return; + } + ToolbarContentTintHelper.handleOnPrepareOptionsMenu(activity, toolbar); + } + + @SuppressWarnings("ConstantConditions") + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + //if (pager == null) return false; + Fragment currentFragment = getCurrentFragment(); + if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment) { + AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment; + if (handleGridSizeMenuItem(fragment, item)) { + return true; + } + if (handleSortOrderMenuItem(fragment, item)) { + return true; + } + } + int id = item.getItemId(); + switch (id) { + case R.id.action_new_playlist: + CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST"); + return true; + case R.id.action_shuffle_all: + MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(getContext()) + .blockingFirst(), true); + return true; + case R.id.action_search: + NavigationUtil.goToSearch(getMainActivity()); + break; + case R.id.action_equalizer: + NavigationUtil.openEqualizer(getActivity()); + return true; + case R.id.action_sleep_timer: + if (getFragmentManager() != null) { + new SleepTimerDialog().show(getFragmentManager(), TAG); + } + return true; + case R.id.action_settings: + startActivity(new Intent(getContext(), SettingsActivity.class)); + break; + } + return super.onOptionsItemSelected(item); + } + + + private void setUpGridSizeMenu( + @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, + @NonNull SubMenu gridSizeMenu) { + switch (fragment.getGridSize()) { + case 1: + gridSizeMenu.findItem(R.id.action_grid_size_1).setChecked(true); + break; + case 2: + gridSizeMenu.findItem(R.id.action_grid_size_2).setChecked(true); + break; + case 3: + gridSizeMenu.findItem(R.id.action_grid_size_3).setChecked(true); + break; + case 4: + gridSizeMenu.findItem(R.id.action_grid_size_4).setChecked(true); + break; + case 5: + gridSizeMenu.findItem(R.id.action_grid_size_5).setChecked(true); + break; + case 6: + gridSizeMenu.findItem(R.id.action_grid_size_6).setChecked(true); + break; + case 7: + gridSizeMenu.findItem(R.id.action_grid_size_7).setChecked(true); + break; + case 8: + gridSizeMenu.findItem(R.id.action_grid_size_8).setChecked(true); + break; + } + int maxGridSize = fragment.getMaxGridSize(); + if (maxGridSize < 8) { + gridSizeMenu.findItem(R.id.action_grid_size_8).setVisible(false); + } + if (maxGridSize < 7) { + gridSizeMenu.findItem(R.id.action_grid_size_7).setVisible(false); + } + if (maxGridSize < 6) { + gridSizeMenu.findItem(R.id.action_grid_size_6).setVisible(false); + } + if (maxGridSize < 5) { + gridSizeMenu.findItem(R.id.action_grid_size_5).setVisible(false); + } + if (maxGridSize < 4) { + gridSizeMenu.findItem(R.id.action_grid_size_4).setVisible(false); + } + if (maxGridSize < 3) { + gridSizeMenu.findItem(R.id.action_grid_size_3).setVisible(false); + } + } + + + private boolean handleGridSizeMenuItem( + @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) { + int gridSize = 0; + switch (item.getItemId()) { + case R.id.action_grid_size_1: + gridSize = 1; + break; + case R.id.action_grid_size_2: + gridSize = 2; + break; + case R.id.action_grid_size_3: + gridSize = 3; + break; + case R.id.action_grid_size_4: + gridSize = 4; + break; + case R.id.action_grid_size_5: + gridSize = 5; + break; + case R.id.action_grid_size_6: + gridSize = 6; + break; + case R.id.action_grid_size_7: + gridSize = 7; + break; + case R.id.action_grid_size_8: + gridSize = 8; + break; } - public int getTotalAppBarScrollingRange() { - return appbar.getTotalScrollRange(); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_library, container, false); - unBinder = ButterKnife.bind(this, view); - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - setStatusbarColorAuto(view); - - getMainActivity().setBottomBarVisibility(View.VISIBLE); - setupToolbar(); - if (getArguments() == 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; - } - } - - private void setupToolbar() { - //noinspection ConstantConditions - int primaryColor = ThemeStore.primaryColor(getContext()); - appbar.setBackgroundColor(primaryColor); - toolbar.setBackgroundColor(primaryColor); - toolbar.setTitle(R.string.library); - appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> - getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext()))); - Objects.requireNonNull(getActivity()).setTitle(R.string.app_name); - getMainActivity().setSupportActionBar(toolbar); - } - - public Fragment getCurrentFragment() { - if (fragmentManager == null) { - return SongsFragment.newInstance(); - } - return fragmentManager.findFragmentByTag(LibraryFragment.TAG); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - unBinder.unbind(); - } - - @Override - public boolean handleBackPress() { - if (cab != null && cab.isActive()) { - cab.finish(); - return true; - } - return false; - } - - public void selectedFragment(Fragment fragment) { - fragmentManager = getChildFragmentManager(); - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - - fragmentTransaction - .replace(R.id.fragment_container, fragment, TAG) - .commit(); - } - - @NonNull - @Override - public MaterialCab openCab(int menuRes, MaterialCab.Callback callback) { - if (cab != null && cab.isActive()) { - cab.finish(); - } - //noinspection ConstantConditions - cab = new MaterialCab(getMainActivity(), R.id.cab_stub) - .setMenu(menuRes) - .setCloseDrawableRes(R.drawable.ic_close_white_24dp) - .setBackgroundColor( - RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(getActivity()))) - .start(callback); - return cab; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.menu_main, menu); - - Fragment currentFragment = getCurrentFragment(); - if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment - && currentFragment.isAdded()) { - AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment; - - MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size); - if (RetroUtil.isLandscape(getResources())) { - gridSizeItem.setTitle(R.string.action_grid_size_land); - } - setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu()); - - setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu()); - - } else { - menu.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title); - menu.removeItem(R.id.action_grid_size); - } - Activity activity = getActivity(); - if (activity == null) { - return; - } - ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu, - ATHToolbarActivity.getToolbarBackgroundColor(toolbar)); - } - - private void setUpSortOrderMenu( - @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, - @NonNull SubMenu sortOrderMenu) { - String currentSortOrder = fragment.getSortOrder(); - sortOrderMenu.clear(); - - if (fragment instanceof AlbumsFragment) { - sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z) - .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z)); - sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a) - .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A)); - sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist) - .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST)); - sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year) - .setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR)); - } else if (fragment instanceof ArtistsFragment) { - sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z) - .setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z)); - sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a) - .setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A)); - } else if (fragment instanceof SongsFragment) { - sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z)); - sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A)); - sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST)); - sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM)); - sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR)); - sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date) - .setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE)); - } - - sortOrderMenu.setGroupCheckable(0, true, true); - } - - private boolean handleSortOrderMenuItem( - @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) { - String sortOrder = null; - if (fragment instanceof AlbumsFragment) { - switch (item.getItemId()) { - case R.id.action_album_sort_order_asc: - sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z; - break; - case R.id.action_album_sort_order_desc: - sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A; - break; - case R.id.action_album_sort_order_artist: - sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST; - break; - case R.id.action_album_sort_order_year: - sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR; - break; - } - } else if (fragment instanceof ArtistsFragment) { - switch (item.getItemId()) { - case R.id.action_artist_sort_order_asc: - sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z; - break; - case R.id.action_artist_sort_order_desc: - sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A; - break; - } - } else if (fragment instanceof SongsFragment) { - switch (item.getItemId()) { - case R.id.action_song_sort_order_asc: - sortOrder = SortOrder.SongSortOrder.SONG_A_Z; - break; - case R.id.action_song_sort_order_desc: - sortOrder = SortOrder.SongSortOrder.SONG_Z_A; - break; - case R.id.action_song_sort_order_artist: - sortOrder = SortOrder.SongSortOrder.SONG_ARTIST; - break; - case R.id.action_song_sort_order_album: - sortOrder = SortOrder.SongSortOrder.SONG_ALBUM; - break; - case R.id.action_song_sort_order_year: - sortOrder = SortOrder.SongSortOrder.SONG_YEAR; - break; - case R.id.action_song_sort_order_date: - sortOrder = SortOrder.SongSortOrder.SONG_DATE; - break; - } - } - - if (sortOrder != null) { - item.setChecked(true); - fragment.setAndSaveSortOrder(sortOrder); - return true; - } - - return false; - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - Activity activity = getActivity(); - if (activity == null) { - return; - } - ToolbarContentTintHelper.handleOnPrepareOptionsMenu(activity, toolbar); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - //if (pager == null) return false; - Fragment currentFragment = getCurrentFragment(); - if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment) { - AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment; - if (handleGridSizeMenuItem(fragment, item)) { - return true; - } - if (handleSortOrderMenuItem(fragment, item)) { - return true; - } - } - int id = item.getItemId(); - switch (id) { - case R.id.action_new_playlist: - CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST"); - return true; - case R.id.action_shuffle_all: - //noinspection ConstantConditions - SongLoader.getAllSongs(getContext()).subscribeOn(Schedulers.computation()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(songs -> MusicPlayerRemote.openAndShuffleQueue(songs, true)); - return true; - case R.id.action_search: - startActivity(new Intent(getActivity(), SearchActivity.class)); - return true; - case R.id.action_equalizer: - //noinspection ConstantConditions - NavigationUtil.openEqualizer(getActivity()); - return true; - case R.id.action_sleep_timer: - if (getFragmentManager() != null) { - new SleepTimerDialog().show(getFragmentManager(), TAG); - } - return true; - case R.id.action_settings: - startActivity(new Intent(getContext(), SettingsActivity.class)); - break; - } - return super.onOptionsItemSelected(item); - } - - private void setUpGridSizeMenu( - @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, - @NonNull SubMenu gridSizeMenu) { - switch (fragment.getGridSize()) { - case 1: - gridSizeMenu.findItem(R.id.action_grid_size_1).setChecked(true); - break; - case 2: - gridSizeMenu.findItem(R.id.action_grid_size_2).setChecked(true); - break; - case 3: - gridSizeMenu.findItem(R.id.action_grid_size_3).setChecked(true); - break; - case 4: - gridSizeMenu.findItem(R.id.action_grid_size_4).setChecked(true); - break; - case 5: - gridSizeMenu.findItem(R.id.action_grid_size_5).setChecked(true); - break; - case 6: - gridSizeMenu.findItem(R.id.action_grid_size_6).setChecked(true); - break; - case 7: - gridSizeMenu.findItem(R.id.action_grid_size_7).setChecked(true); - break; - case 8: - gridSizeMenu.findItem(R.id.action_grid_size_8).setChecked(true); - break; - } - int maxGridSize = fragment.getMaxGridSize(); - if (maxGridSize < 8) { - gridSizeMenu.findItem(R.id.action_grid_size_8).setVisible(false); - } - if (maxGridSize < 7) { - gridSizeMenu.findItem(R.id.action_grid_size_7).setVisible(false); - } - if (maxGridSize < 6) { - gridSizeMenu.findItem(R.id.action_grid_size_6).setVisible(false); - } - if (maxGridSize < 5) { - gridSizeMenu.findItem(R.id.action_grid_size_5).setVisible(false); - } - if (maxGridSize < 4) { - gridSizeMenu.findItem(R.id.action_grid_size_4).setVisible(false); - } - if (maxGridSize < 3) { - gridSizeMenu.findItem(R.id.action_grid_size_3).setVisible(false); - } - } - - - private boolean handleGridSizeMenuItem( - @NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) { - int gridSize = 0; - switch (item.getItemId()) { - case R.id.action_grid_size_1: - gridSize = 1; - break; - case R.id.action_grid_size_2: - gridSize = 2; - break; - case R.id.action_grid_size_3: - gridSize = 3; - break; - case R.id.action_grid_size_4: - gridSize = 4; - break; - case R.id.action_grid_size_5: - gridSize = 5; - break; - case R.id.action_grid_size_6: - gridSize = 6; - break; - case R.id.action_grid_size_7: - gridSize = 7; - break; - case R.id.action_grid_size_8: - gridSize = 8; - break; - } - - if (gridSize > 0) { - item.setChecked(true); - fragment.setAndSaveGridSize(gridSize); - return true; - } - return false; + if (gridSize > 0) { + item.setChecked(true); + fragment.setAndSaveGridSize(gridSize); + return true; } + return false; + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/PlaylistsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/PlaylistsFragment.java index 2850ed94..2d220d98 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/PlaylistsFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/PlaylistsFragment.java @@ -54,14 +54,14 @@ public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment implements - SongContract.SongView { + AbsLibraryPagerRecyclerViewCustomGridSizeFragment implements + SongContract.SongView { - private static final String TAG = "Songs"; - private SongPresenter presenter; + private SongPresenter presenter; - public SongsFragment() { - // Required empty public constructor + 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 dataSet = + getAdapter() == null ? new ArrayList() : getAdapter().getDataSet(); + + if (getGridSize() <= getMaxGridSizeForList()) { + return new ShuffleButtonSongAdapter(getLibraryFragment().getMainActivity(), dataSet, + itemLayoutRes, usePalette, getLibraryFragment()); } + return new SongAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, + usePalette, getLibraryFragment()); + } - public static SongsFragment newInstance() { - Bundle args = new Bundle(); - SongsFragment fragment = new SongsFragment(); - fragment.setArguments(args); - return fragment; + @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(); } + } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - presenter = new SongPresenter(this); + @Override + public void setMenuVisibility(boolean menuVisible) { + super.setMenuVisibility(menuVisible); + if (menuVisible) { + getLibraryFragment().setTitle( + PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library + : R.string.songs); } + } - @NonNull - @Override - protected GridLayoutManager createLayoutManager() { - return new GridLayoutManager(getActivity(), getGridSize()); - } + @Override + public void onDestroy() { + presenter.unsubscribe(); + super.onDestroy(); + } - @Override - protected int getEmptyMessage() { - return R.string.no_songs; - } + @Override + public void loading() { - @NonNull - @Override - protected SongAdapter createAdapter() { - int itemLayoutRes = getItemLayoutRes(); - notifyLayoutResChanged(itemLayoutRes); - boolean usePalette = loadUsePalette(); - ArrayList dataSet = - getAdapter() == null ? new ArrayList() : getAdapter().getDataSet(); + } - if (getGridSize() <= getMaxGridSizeForList()) { - return new ShuffleButtonSongAdapter(getLibraryFragment().getMainActivity(), dataSet, - itemLayoutRes, usePalette, getLibraryFragment()); - } - return new SongAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, - usePalette, getLibraryFragment()); - } + @Override + public void showData(ArrayList songs) { + getAdapter().swapDataSet(songs); + } - @Override - public void onMediaStoreChanged() { - presenter.loadSongs(); - } + @Override + public void showEmptyView() { + getAdapter().swapDataSet(new ArrayList()); + } - @Override - protected int loadGridSize() { - return PreferenceUtil.getInstance(getActivity()).getSongGridSize(getActivity()); - } + @Override + public void completed() { - @Override - protected void saveGridSize(int gridSize) { - PreferenceUtil.getInstance(getActivity()).setSongGridSize(gridSize); - } + } - @Override - protected int loadGridSizeLand() { - return PreferenceUtil.getInstance(getActivity()).getSongGridSizeLand(getActivity()); - } + @Override + protected String loadSortOrder() { + return PreferenceUtil.getInstance(getActivity()).getSongSortOrder(); + } - @Override - protected void saveGridSizeLand(int gridSize) { - PreferenceUtil.getInstance(getActivity()).setSongGridSizeLand(gridSize); - } + @Override + protected void saveSortOrder(String sortOrder) { + PreferenceUtil.getInstance(getActivity()).setSongSortOrder(sortOrder); + } - @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().getToolbar().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().getToolbar().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 songs) { - getAdapter().swapDataSet(songs); - } - - @Override - public void showEmptyView() { - getAdapter().swapDataSet(new ArrayList()); - } - - @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(); - } + @Override + protected void setSortOrder(String sortOrder) { + presenter.loadSongs(); + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java index 3109a5f6..19a04fb4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java @@ -24,6 +24,7 @@ import android.view.View; import android.view.ViewGroup; import android.webkit.MimeTypeMap; import android.widget.PopupMenu; +import android.widget.TextView; import android.widget.Toast; import butterknife.BindView; import butterknife.ButterKnife; @@ -31,6 +32,8 @@ 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.TintHelper; import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper; import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.helper.MusicPlayerRemote; @@ -82,6 +85,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements CoordinatorLayout coordinatorLayout; @BindView(R.id.container) View container; + @BindView(R.id.title) + TextView title; @BindView(android.R.id.empty) View empty; @BindView(R.id.toolbar) @@ -90,10 +95,10 @@ public class FoldersFragment extends AbsMainActivityFragment implements BreadCrumbLayout breadCrumbs; @BindView(R.id.appbar) AppBarLayout appbar; - @BindView(R.id.status_bar) - View statusBar; + @BindView(R.id.recycler_view) FastScrollRecyclerView recyclerView; + Comparator fileComparator = (lhs, rhs) -> { if (lhs.isDirectory() && !rhs.isDirectory()) { return -1; @@ -207,7 +212,6 @@ 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(); @@ -215,24 +219,29 @@ public class FoldersFragment extends AbsMainActivityFragment implements setUpBreadCrumbs(); setUpRecyclerView(); setUpAdapter(); - ViewUtil.setStatusBarHeight(getContext(), statusBar); + } private void setUpAppbarColor() { //noinspection ConstantConditions int primaryColor = ThemeStore.primaryColor(getActivity()); - appbar.setBackgroundColor(primaryColor); - toolbar.setBackgroundColor(primaryColor); + TintHelper.setTintAuto(container, primaryColor, true); + appbar.setBackgroundColor(ColorUtil.darkenColor(primaryColor)); + toolbar.setBackgroundColor(ColorUtil.darkenColor(primaryColor)); //breadCrumbs.setBackgroundColor(primaryColor); breadCrumbs.setActivatedContentColor( - ToolbarContentTintHelper.toolbarTitleColor(getActivity(), primaryColor)); + ToolbarContentTintHelper + .toolbarTitleColor(getActivity(), ColorUtil.darkenColor(primaryColor))); breadCrumbs.setDeactivatedContentColor( - ToolbarContentTintHelper.toolbarSubtitleColor(getActivity(), primaryColor)); + 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); diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/HomeFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/HomeFragment.java index 803d45ed..8abe1dd6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/HomeFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/HomeFragment.java @@ -1,8 +1,5 @@ package code.name.monkey.retromusic.ui.fragments.mainactivity.home; -import static code.name.monkey.retromusic.Constants.USER_BANNER; -import static code.name.monkey.retromusic.Constants.USER_PROFILE; - import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle; @@ -23,6 +20,15 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + +import java.io.File; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Random; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -55,357 +61,354 @@ import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.RetroUtil; import code.name.monkey.retromusic.views.CircularImageView; import code.name.monkey.retromusic.views.MetalRecyclerViewPager; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; -import java.io.File; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Random; + +import static code.name.monkey.retromusic.Constants.USER_BANNER; +import static code.name.monkey.retromusic.Constants.USER_PROFILE; public class HomeFragment extends AbsMainActivityFragment implements MainActivityFragmentCallbacks, - HomeContract.HomeView { + HomeContract.HomeView { - private static final String TAG = "HomeFragment"; - Unbinder unbinder; - @BindView(R.id.home_toolbar) - Toolbar toolbar; - @BindView(R.id.appbar) - 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.title) - TextView title; - @BindView(R.id.search) - ImageView search; + private static final String TAG = "HomeFragment"; + Unbinder unbinder; + @BindView(R.id.home_toolbar) + Toolbar toolbar; + @BindView(R.id.appbar) + 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.title) + TextView title; + @BindView(R.id.search) + ImageView search; - private HomePresenter homePresenter; - private CompositeDisposable disposable; + private HomePresenter homePresenter; + private CompositeDisposable disposable; - public static HomeFragment newInstance() { - Bundle args = new Bundle(); - HomeFragment fragment = new HomeFragment(); - fragment.setArguments(args); - return fragment; - } - - private void getTimeOfTheDay() { - Calendar c = Calendar.getInstance(); - int timeOfDay = c.get(Calendar.HOUR_OF_DAY); - - String[] images = new String[]{}; - if (timeOfDay >= 0 && timeOfDay < 6) { - images = getResources().getStringArray(R.array.night); - } else if (timeOfDay >= 6 && timeOfDay < 12) { - images = getResources().getStringArray(R.array.morning); - } else if (timeOfDay >= 12 && timeOfDay < 16) { - images = getResources().getStringArray(R.array.after_noon); - } else if (timeOfDay >= 16 && timeOfDay < 20) { - images = getResources().getStringArray(R.array.evening); - } else if (timeOfDay >= 20 && timeOfDay < 24) { - images = getResources().getStringArray(R.array.night); - } - String day = images[new Random().nextInt(images.length)]; - loadTimeImage(day); - } - - private void loadTimeImage(String day) { - //noinspection ConstantConditions - if (PreferenceUtil.getInstance(getActivity()).getBannerImage().isEmpty()) { - if (imageView != null) { - Glide.with(getActivity()).load(day) - .asBitmap() - .placeholder(R.drawable.material_design_default) - .diskCacheStrategy(DiskCacheStrategy.SOURCE) - .into(imageView); - } - } else { - loadBannerFromStorage(); - } - } - - private void loadBannerFromStorage() { - //noinspection ConstantConditions - disposable.add(new Compressor(getContext()) - .setQuality(100) - .setCompressFormat(Bitmap.CompressFormat.WEBP) - .compressToBitmapAsFlowable( - new File(PreferenceUtil.getInstance(getContext()).getBannerImage(), USER_BANNER)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(imageView::setImageBitmap)); - } - - private void loadImageFromStorage(ImageView imageView) { - //noinspection ConstantConditions - disposable.add(new Compressor(getContext()) - .setMaxHeight(300) - .setMaxWidth(300) - .setQuality(75) - .setCompressFormat(Bitmap.CompressFormat.WEBP) - .compressToBitmapAsFlowable( - new File(PreferenceUtil.getInstance(getContext()).getProfileImage(), USER_PROFILE)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(imageView::setImageBitmap, - throwable -> imageView.setImageDrawable(ContextCompat - .getDrawable(getContext(), R.drawable.ic_person_flat)))); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - disposable = new CompositeDisposable(); - //noinspection ConstantConditions - homePresenter = new HomePresenter(this); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_home, container, false); - unbinder = ButterKnife.bind(this, view); - return view; - } - - @Override - public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - getMainActivity().getSlidingUpPanelLayout().setShadowHeight(8); - getMainActivity().setBottomBarVisibility(View.VISIBLE); - - setupToolbar(); - loadImageFromStorage(userImage); - - homePresenter.subscribe(); - checkPadding(); - getTimeOfTheDay(); - } - - @SuppressWarnings("ConstantConditions") - private void setupToolbar() { - if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar - .getLayoutParams(); - params.topMargin = RetroUtil.getStatusBarHeight(getContext()); - toolbar.setLayoutParams(params); + public static HomeFragment newInstance() { + Bundle args = new Bundle(); + HomeFragment fragment = new HomeFragment(); + fragment.setArguments(args); + return fragment; } - appbar.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - int color; - switch (state) { - case COLLAPSED: - getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())); - color = ThemeStore.textColorPrimary(getContext()); - break; - default: - case EXPANDED: - case IDLE: - getMainActivity().setLightStatusbar(false); - color = ContextCompat.getColor(getContext(), R.color.md_white_1000); - break; + private void getTimeOfTheDay() { + Calendar c = Calendar.getInstance(); + int timeOfDay = c.get(Calendar.HOUR_OF_DAY); + + String[] images = new String[]{}; + if (timeOfDay >= 0 && timeOfDay < 6) { + images = getResources().getStringArray(R.array.night); + } else if (timeOfDay >= 6 && timeOfDay < 12) { + images = getResources().getStringArray(R.array.morning); + } else if (timeOfDay >= 12 && timeOfDay < 16) { + images = getResources().getStringArray(R.array.after_noon); + } else if (timeOfDay >= 16 && timeOfDay < 20) { + images = getResources().getStringArray(R.array.evening); + } else if (timeOfDay >= 20 && timeOfDay < 24) { + images = getResources().getStringArray(R.array.night); } - TintHelper.setTintAuto(search, color, false); - title.setTextColor(color); - } - }); - - int primaryColor = ThemeStore.primaryColor(getContext()); - - TintHelper.setTintAuto(container, primaryColor, true); - toolbarLayout.setStatusBarScrimColor(primaryColor); - toolbarLayout.setContentScrimColor(primaryColor); - - toolbar.setTitle(R.string.home); - getMainActivity().setSupportActionBar(toolbar); - - } - - @Override - public boolean handleBackPress() { - return false; - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - unbinder.unbind(); - disposable.clear(); - homePresenter.unsubscribe(); - } - - @Override - public void loading() { - - } - - @Override - public void showEmptyView() { - - } - - @Override - public void completed() { - - } - - @Override - public void showData(ArrayList homes) { - //homeAdapter.swapDataSet(homes); - } - - @Override - public void onMediaStoreChanged() { - super.onMediaStoreChanged(); - homePresenter.subscribe(); - } - - @Override - public void onServiceConnected() { - super.onServiceConnected(); - checkPadding(); - } - - @Override - public void onQueueChanged() { - super.onQueueChanged(); - checkPadding(); - } - - private void checkPadding() { - int height = getResources().getDimensionPixelSize(R.dimen.mini_player_height); - container.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0); - } - - @Override - public void recentArtist(ArrayList artists) { - recentArtistContainer.setVisibility(View.VISIBLE); - recentArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(), - 1, GridLayoutManager.HORIZONTAL, false)); - ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists, - R.layout.item_artist, false, null); - recentArtistRV.setAdapter(artistAdapter); - } - - @Override - public void recentAlbum(ArrayList albums) { - recentAlbumsContainer.setVisibility(View.VISIBLE); - AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(), - getDisplayMetrics()); - artistAdapter.swapData(albums); - recentAlbumRV.setAdapter(artistAdapter); - } - - @Override - public void topArtists(ArrayList artists) { - topArtistContainer.setVisibility(View.VISIBLE); - topArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(), - 1, GridLayoutManager.HORIZONTAL, false)); - ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists, - R.layout.item_artist, false, null); - topArtistRV.setAdapter(artistAdapter); - - } - - @Override - public void topAlbums(ArrayList albums) { - topAlbumContainer.setVisibility(View.VISIBLE); - AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(), - getDisplayMetrics()); - artistAdapter.swapData(albums); - topAlbumRV.setAdapter(artistAdapter); - } - - private DisplayMetrics getDisplayMetrics() { - Display display = getMainActivity().getWindowManager().getDefaultDisplay(); - DisplayMetrics metrics = new DisplayMetrics(); - display.getMetrics(metrics); - - return metrics; - } - - @Override - public void suggestions(ArrayList playlists) { - - } - - - @Override - public void geners(ArrayList genres) { - genreContainer.setVisibility(View.VISIBLE); - genresRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - //noinspection ConstantConditions - GenreAdapter genreAdapter = new GenreAdapter(getActivity(), genres, R.layout.item_list); - genresRecyclerView.setAdapter(genreAdapter); - } - - - @OnClick({R.id.last_added, R.id.top_played, R.id.action_shuffle, R.id.history, - R.id.user_image, R.id.search}) - 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); - break; - case R.id.last_added: - NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity)); - break; - case R.id.top_played: - NavigationUtil.goToPlaylistNew(activity, new MyTopTracksPlaylist(activity)); - break; - 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; - } + String day = images[new Random().nextInt(images.length)]; + loadTimeImage(day); } - } - @Override - public void onPlayingMetaChanged() { - super.onPlayingMetaChanged(); - homePresenter.loadRecentArtists(); - homePresenter.loadRecentAlbums(); - } + private void loadTimeImage(String day) { + //noinspection ConstantConditions + if (PreferenceUtil.getInstance(getActivity()).getBannerImage().isEmpty()) { + if (imageView != null) { + Glide.with(getActivity()).load(day) + .asBitmap() + .placeholder(R.drawable.material_design_default) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .into(imageView); + } + } else { + loadBannerFromStorage(); + } + } + + private void loadBannerFromStorage() { + //noinspection ConstantConditions + disposable.add(new Compressor(getContext()) + .setQuality(100) + .setCompressFormat(Bitmap.CompressFormat.WEBP) + .compressToBitmapAsFlowable( + new File(PreferenceUtil.getInstance(getContext()).getBannerImage(), USER_BANNER)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(imageView::setImageBitmap)); + } + + private void loadImageFromStorage(ImageView imageView) { + //noinspection ConstantConditions + disposable.add(new Compressor(getContext()) + .setMaxHeight(300) + .setMaxWidth(300) + .setQuality(75) + .setCompressFormat(Bitmap.CompressFormat.WEBP) + .compressToBitmapAsFlowable( + new File(PreferenceUtil.getInstance(getContext()).getProfileImage(), USER_PROFILE)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(imageView::setImageBitmap, + throwable -> imageView.setImageDrawable(ContextCompat + .getDrawable(getContext(), R.drawable.ic_person_flat)))); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + disposable = new CompositeDisposable(); + //noinspection ConstantConditions + homePresenter = new HomePresenter(this); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_home, container, false); + unbinder = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + getMainActivity().getSlidingUpPanelLayout().setShadowHeight(8); + getMainActivity().setBottomBarVisibility(View.VISIBLE); + + setupToolbar(); + loadImageFromStorage(userImage); + + homePresenter.subscribe(); + checkPadding(); + getTimeOfTheDay(); + } + + @SuppressWarnings("ConstantConditions") + private void setupToolbar() { + if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) { + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar + .getLayoutParams(); + params.topMargin = RetroUtil.getStatusBarHeight(getContext()); + toolbar.setLayoutParams(params); + } + + appbar.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + int color; + switch (state) { + case COLLAPSED: + getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())); + color = ThemeStore.textColorPrimary(getContext()); + break; + default: + case EXPANDED: + case IDLE: + getMainActivity().setLightStatusbar(false); + 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); + toolbarLayout.setStatusBarScrimColor(primaryColor); + toolbarLayout.setContentScrimColor(primaryColor); + + toolbar.setTitle(R.string.home); + getMainActivity().setSupportActionBar(toolbar); + + } + + @Override + public boolean handleBackPress() { + return false; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + unbinder.unbind(); + disposable.clear(); + homePresenter.unsubscribe(); + } + + @Override + public void loading() { + + } + + @Override + public void showEmptyView() { + + } + + @Override + public void completed() { + + } + + @Override + public void showData(ArrayList homes) { + //homeAdapter.swapDataSet(homes); + } + + @Override + public void onMediaStoreChanged() { + super.onMediaStoreChanged(); + homePresenter.subscribe(); + } + + @Override + public void onServiceConnected() { + super.onServiceConnected(); + checkPadding(); + } + + @Override + public void onQueueChanged() { + super.onQueueChanged(); + checkPadding(); + } + + private void checkPadding() { + int height = getResources().getDimensionPixelSize(R.dimen.mini_player_height); + container.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0); + } + + @Override + public void recentArtist(ArrayList artists) { + recentArtistContainer.setVisibility(View.VISIBLE); + recentArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(), + 1, GridLayoutManager.HORIZONTAL, false)); + ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists, + R.layout.item_artist, false, null); + recentArtistRV.setAdapter(artistAdapter); + } + + @Override + public void recentAlbum(ArrayList albums) { + recentAlbumsContainer.setVisibility(View.VISIBLE); + AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(), + getDisplayMetrics()); + artistAdapter.swapData(albums); + recentAlbumRV.setAdapter(artistAdapter); + } + + @Override + public void topArtists(ArrayList artists) { + topArtistContainer.setVisibility(View.VISIBLE); + topArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(), + 1, GridLayoutManager.HORIZONTAL, false)); + ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists, + R.layout.item_artist, false, null); + topArtistRV.setAdapter(artistAdapter); + + } + + @Override + public void topAlbums(ArrayList albums) { + topAlbumContainer.setVisibility(View.VISIBLE); + AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(), + getDisplayMetrics()); + artistAdapter.swapData(albums); + topAlbumRV.setAdapter(artistAdapter); + } + + private DisplayMetrics getDisplayMetrics() { + Display display = getMainActivity().getWindowManager().getDefaultDisplay(); + DisplayMetrics metrics = new DisplayMetrics(); + display.getMetrics(metrics); + + return metrics; + } + + @Override + public void suggestions(ArrayList playlists) { + + } + + + @Override + public void geners(ArrayList genres) { + genreContainer.setVisibility(View.VISIBLE); + genresRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + //noinspection ConstantConditions + GenreAdapter genreAdapter = new GenreAdapter(getActivity(), genres, R.layout.item_list); + genresRecyclerView.setAdapter(genreAdapter); + } + + + @OnClick({R.id.last_added, R.id.top_played, R.id.action_shuffle, R.id.history, + R.id.user_image, R.id.search}) + 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); + break; + case R.id.last_added: + NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity)); + break; + case R.id.top_played: + NavigationUtil.goToPlaylistNew(activity, new MyTopTracksPlaylist(activity)); + break; + 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; + } + } + } + + @Override + public void onPlayingMetaChanged() { + super.onPlayingMetaChanged(); + homePresenter.loadRecentArtists(); + homePresenter.loadRecentAlbums(); + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/plain/PlainPlaybackControlsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/plain/PlainPlaybackControlsFragment.java index c32d8397..e7a3841f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/plain/PlainPlaybackControlsFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/plain/PlainPlaybackControlsFragment.java @@ -16,20 +16,19 @@ import android.view.animation.LinearInterpolator; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; - -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.misc.SimpleOnSeekbarChangeListener; - 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.helper.MusicPlayerRemote; import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper; +import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener; import code.name.monkey.retromusic.service.MusicService; import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment; import code.name.monkey.retromusic.util.MusicUtil; @@ -41,284 +40,297 @@ import code.name.monkey.retromusic.views.PlayPauseDrawable; */ public class PlainPlaybackControlsFragment 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_progress_slider) - SeekBar progressSlider; - @BindView(R.id.player_song_total_time) - TextView songTotalTime; - @BindView(R.id.player_song_current_progress) - TextView songCurrentProgress; - @BindView(R.id.volume_fragment_container) - View volumeContainer; - private Unbinder unbinder; - private PlayPauseDrawable playerFabPlayPauseDrawable; - private int lastPlaybackControlsColor; - private int lastDisabledPlaybackControlsColor; - private MusicProgressViewUpdateHelper progressViewUpdateHelper; - @Override - public void onPlayStateChanged() { - updatePlayPauseDrawableState(true); + @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_progress_slider) + SeekBar progressSlider; + @BindView(R.id.player_song_total_time) + TextView songTotalTime; + @BindView(R.id.player_song_current_progress) + TextView songCurrentProgress; + @BindView(R.id.volume_fragment_container) + View volumeContainer; + 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(); + } + + @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_plain_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(); + if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) { + volumeContainer.setVisibility(View.VISIBLE); + } else { + volumeContainer.setVisibility(View.GONE); } + } - @Override - public void onRepeatModeChanged() { - updateRepeatState(); + 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; } + } - @Override - public void onShuffleModeChanged() { - updateShuffleState(); + 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; } + } - @Override - public void onServiceConnected() { - updatePlayPauseDrawableState(false); - updateRepeatState(); - updateShuffleState(); + + @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); } + } - @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_plain_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(); - if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) { - volumeContainer.setVisibility(View.VISIBLE); - } else { - volumeContainer.setVisibility(View.GONE); + @Override + protected void setUpProgressSlider() { + progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) { + MusicPlayerRemote.seekTo(progress); + onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), + MusicPlayerRemote.getSongDurationMillis()); } + } + }); + } + + 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) { + progressSlider.setMax(total); + + ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress); + animator.setDuration(1500); + animator.setInterpolator(new LinearInterpolator()); + animator.start(); + + songTotalTime.setText(MusicUtil.getReadableDurationString(total)); + songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress)); + } + + @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); } - private void setUpMusicControllers() { - setUpPlayPauseFab(); - setUpPrevNext(); - setUpRepeatButton(); - setUpShuffleButton(); - setUpProgressSlider(); + if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) { + TintHelper.setTintAuto(playPauseFab, + MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)), + false); + TintHelper.setTintAuto(playPauseFab, dark, true); + setProgressBarColor(dark); + } else { + int accentColor = ThemeStore.accentColor(getContext()); + setProgressBarColor(accentColor); + TintHelper.setTintAuto(playPauseFab, + MaterialValueHelper + .getPrimaryTextColor(getContext(), ColorUtil.isColorLight(accentColor)), + false); + TintHelper.setTintAuto(playPauseFab, accentColor, true); } + updateRepeatState(); + updateShuffleState(); + updatePrevNextColor(); + } - private void setUpPrevNext() { - updatePrevNextColor(); - nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong()); - prevButton.setOnClickListener(v -> MusicPlayerRemote.back()); - } + public void setProgressBarColor(int newColor) { + LayerDrawable ld = (LayerDrawable) progressSlider.getProgressDrawable(); + ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress); + clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN); + } - private void updatePrevNextColor() { - nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN); - prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN); - } + private void setUpPlayPauseFab() { + playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity()); - 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; - } - } - - - @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); - } - } - - @Override - protected void setUpProgressSlider() { - progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) { - MusicPlayerRemote.seekTo(progress); - onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis()); - } - } - }); - } - - public void showBouceAnimation() { - playPauseFab.clearAnimation(); - - playPauseFab.setScaleX(0.9f); - playPauseFab.setScaleY(0.9f); - playPauseFab.setVisibility(View.VISIBLE); + 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); + } + }); + } - 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) { - progressSlider.setMax(total); - - ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress); - animator.setDuration(1500); - animator.setInterpolator(new LinearInterpolator()); - animator.start(); - - songTotalTime.setText(MusicUtil.getReadableDurationString(total)); - songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress)); - } - - @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); - setProgressBarColor(progressSlider, dark); - } - updateRepeatState(); - updateShuffleState(); - updatePrevNextColor(); - } - - public void setProgressBarColor(SeekBar progressBar, int newColor) { - LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable(); - ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress); - clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN); - } - - 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); - } + protected void updatePlayPauseDrawableState(boolean animate) { + if (MusicPlayerRemote.isPlaying()) { + playerFabPlayPauseDrawable.setPause(animate); + } else { + playerFabPlayPauseDrawable.setPlay(animate); } + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/simple/SimplePlaybackControlsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/simple/SimplePlaybackControlsFragment.java index 1631a757..6ca30bb6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/simple/SimplePlaybackControlsFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/simple/SimplePlaybackControlsFragment.java @@ -1,8 +1,6 @@ package code.name.monkey.retromusic.ui.fragments.player.simple; 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; @@ -12,9 +10,7 @@ import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.ImageButton; -import android.widget.SeekBar; import android.widget.TextView; - import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -39,281 +35,288 @@ 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 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 onRepeatModeChanged() { - updateRepeatState(); + 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 onShuffleModeChanged() { - updateShuffleState(); - } + updateRepeatState(); + updateShuffleState(); + updatePrevNextColor(); + } - @Override - public void onServiceConnected() { - updatePlayPauseDrawableState(false); - updateRepeatState(); - updateShuffleState(); - updateSong(); - } + private void setUpPlayPauseFab() { + playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity()); - @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.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); + } + }); + } - 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 { - text.setTextColor(ThemeStore.accentColor(getContext())); - } - - updateRepeatState(); - updateShuffleState(); - updatePrevNextColor(); - } - - public void setProgressBarColor(SeekBar progressBar, int newColor) { - LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable(); - ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress); - clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN); - } - - 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); - } + protected void updatePlayPauseDrawableState(boolean animate) { + if (MusicPlayerRemote.isPlaying()) { + playerFabPlayPauseDrawable.setPause(animate); + } else { + playerFabPlayPauseDrawable.setPlay(animate); } + } } diff --git a/appthemehelper/appthemehelper.iml b/appthemehelper/appthemehelper.iml index ad32e524..f59e3726 100644 --- a/appthemehelper/appthemehelper.iml +++ b/appthemehelper/appthemehelper.iml @@ -87,18 +87,15 @@ - - - + - @@ -111,7 +108,7 @@ - + diff --git a/build.gradle b/build.gradle index d9cedb63..89eb994d 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0-alpha15' + classpath 'com.android.tools.build:gradle:3.2.0-alpha18' } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13372aef5e24af05341d49695ee84e5f9b594659..7a3265ee94c0ab25cf079ac8ccdf87f41d455d42 100644 GIT binary patch delta 28638 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 delta 27523 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6eaaee34..a5e86caf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Mon May 14 20:13:41 IST 2018 +#Fri Jul 27 20:58:25 IST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 9d82f789..cccdd3d5 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,42 +6,6 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282a..f9553162 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/public.properties b/public.properties deleted file mode 100755 index 9aa327f4..00000000 --- a/public.properties +++ /dev/null @@ -1,5 +0,0 @@ -# This API key is provided for convenience. Please go to https://www.last.fm/api/account/create and create your own. - -GOOGLE_PLAY_LICENSE_KEY = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnWuCg0k+BBB25J7vZUZeTf5sxzSzJhXLdyj9zRKr2k0Xf/RNAmqSXTfshQiP5dZyTeJ+cpRP4xeKijW66/bTwKgH3h0x48pgn7tQMIEdH9KaZUlPzHH9pcp+N9iJlKhX+vacZUpbnlOp0PjrJXP1Xg6gz1gs3nMDhX1z5Tr4vPKd+Wf7E3tyTc15jpfqSKSzqYzIlT4VFdcmLcPypCwRzgRzWOGqj3/oz8rxLCQ4bxtDHwtZhHAz/N6go5oZodpfrA2ETiyeNsqta2Xmwt38CyYukSQ+eYJ2irZ5wqnr1iN9duzZRfMi7id+tgC8iwicDSanUiYFt/r43C0UkGNx6wIDAQAB -LASTFM_API_KEY=206993ea109315882749d5bc7b2e704d -LASTFM_API_KEY_NEW=17c9e96bc741842d7fc84d3961a25a04