Added now playing queue shett

main
h4h13 2020-01-24 22:24:08 +05:30
parent 24f78d9738
commit 2af26548ee
16 changed files with 432 additions and 112 deletions

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
private static final String TAG = "CustomBottomSheetBehavi";
private boolean allowDragging = true;
public CustomBottomSheetBehavior() {
}
public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (!allowDragging) {
return false;
}
return super.onInterceptTouchEvent(parent, child, event);
}
public void setAllowDragging(boolean allowDragging) {
this.allowDragging = allowDragging;
}
}

View File

@ -0,0 +1,184 @@
/*
* Copyright (c) 2020 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class MultiSheetView extends CoordinatorLayout {
@interface Sheet {
int NONE = 0;
int FIRST = 1;
int SECOND = 2;
}
private static final String TAG = "MultiSheetView";
private CustomBottomSheetBehavior bottomSheetBehavior1;
private CustomBottomSheetBehavior bottomSheetBehavior2;
public MultiSheetView(@NonNull Context context) {
this(context, null);
}
public MultiSheetView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MultiSheetView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public boolean consumeBackPress() {
switch (getCurrentSheet()) {
case Sheet.SECOND:
showSheet(Sheet.FIRST);
return true;
case Sheet.FIRST:
showSheet(Sheet.NONE);
return true;
case Sheet.NONE:
break;
}
return false;
}
@Sheet
public int getCurrentSheet() {
if (bottomSheetBehavior2.getState() == BottomSheetBehavior.STATE_EXPANDED) {
return Sheet.SECOND;
} else if (bottomSheetBehavior1.getState() == BottomSheetBehavior.STATE_EXPANDED) {
return Sheet.FIRST;
} else {
return Sheet.NONE;
}
}
@IdRes
public int getMainContainerResId() {
return R.id.mainContentFrame;
}
@IdRes
public int getSheet1ContainerResId() {
return R.id.playerFragmentContainer;
}
@IdRes
public int getSheet1PeekViewResId() {
return R.id.miniPlayerFragment;
}
@IdRes
public int getSheet2ContainerResId() {
return R.id.sheet2Container;
}
@IdRes
public int getSheet2PeekViewResId() {
return R.id.sheet2PeekView;
}
public void showSheet(@Sheet int sheet) {
// if we are already at our target panel, then don't do anything
if (sheet == getCurrentSheet()) {
return;
}
switch (sheet) {
case Sheet.NONE:
bottomSheetBehavior2.setState(BottomSheetBehavior.STATE_COLLAPSED);
bottomSheetBehavior1.setState(BottomSheetBehavior.STATE_COLLAPSED);
break;
case Sheet.FIRST:
bottomSheetBehavior2.setState(BottomSheetBehavior.STATE_COLLAPSED);
bottomSheetBehavior1.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case Sheet.SECOND:
bottomSheetBehavior2.setState(BottomSheetBehavior.STATE_EXPANDED);
bottomSheetBehavior1.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View sheet1 = findViewById(R.id.slidingPanel);
bottomSheetBehavior1 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet1);
View sheet2 = findViewById(R.id.sheet2);
View thump = findViewById(R.id.thumb);
View extendedToolbar = findViewById(R.id.extendedToolbar);
bottomSheetBehavior2 = (CustomBottomSheetBehavior) BottomSheetBehavior.from(sheet2);
bottomSheetBehavior2.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
bottomSheetBehavior1.setAllowDragging(false);
thump.setRotation(slideOffset * 180);
extendedToolbar.setAlpha(slideOffset);
}
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_EXPANDED
|| newState == BottomSheetBehavior.STATE_DRAGGING) {
bottomSheetBehavior1.setAllowDragging(false);
} else {
bottomSheetBehavior1.setAllowDragging(true);
}
}
});
//First sheet view click listener
findViewById(getSheet1PeekViewResId())
.setOnClickListener(v -> bottomSheetBehavior1.setState(BottomSheetBehavior.STATE_EXPANDED));
// FIXME:
// This click listener (combined with a nested RecyclerView in Sheet 2's container), causes
// the second peek view to stop responding to drag events.
// See `Sheet2Controller`. Remove this ClickListener here to see things working as they should.
//Second sheet view click listener
findViewById(getSheet2PeekViewResId())
.setOnClickListener(v -> bottomSheetBehavior2.setState(BottomSheetBehavior.STATE_EXPANDED));
// FIXED:
// issue was bottomSheetBehavior1 is taking drag event when getSheet2PeekView is dragging
// so detect touch event getSheet2PeekView set bottomSheetBehavior1 dragging false and bottomSheetBehavior2 true
findViewById(getSheet2PeekViewResId()).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(TAG, "onTouch: ");
bottomSheetBehavior1.setAllowDragging(false);
bottomSheetBehavior2.setAllowDragging(true);
return false;
}
});
}
}

View File

@ -6,11 +6,14 @@ import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.MiniPlayerFragment import code.name.monkey.retromusic.fragments.MiniPlayerFragment
@ -52,9 +55,10 @@ import code.name.monkey.retromusic.util.DensityUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.views.BottomNavigationBarTinted import code.name.monkey.retromusic.views.BottomNavigationBarTinted
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.card.MaterialCardView
import kotlinx.android.synthetic.main.sliding_music_panel_layout.bottomNavigationView import kotlinx.android.synthetic.main.sliding_music_panel_layout.bottomNavigationView
import kotlinx.android.synthetic.main.sliding_music_panel_layout.dimBackground import kotlinx.android.synthetic.main.sliding_music_panel_layout.dimBackground
import kotlinx.android.synthetic.main.sliding_music_panel_layout.mainContent
import kotlinx.android.synthetic.main.sliding_music_panel_layout.sheet2Container
import kotlinx.android.synthetic.main.sliding_music_panel_layout.slidingPanel import kotlinx.android.synthetic.main.sliding_music_panel_layout.slidingPanel
abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlayerFragment.Callbacks { abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlayerFragment.Callbacks {
@ -62,7 +66,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
} }
private lateinit var bottomSheetBehavior: BottomSheetBehavior<MaterialCardView> private lateinit var bottomSheetBehavior: BottomSheetBehavior<FrameLayout>
private var miniPlayerFragment: MiniPlayerFragment? = null private var miniPlayerFragment: MiniPlayerFragment? = null
private var playerFragment: AbsPlayerFragment? = null private var playerFragment: AbsPlayerFragment? = null
private var currentNowPlayingScreen: NowPlayingScreen? = null private var currentNowPlayingScreen: NowPlayingScreen? = null
@ -71,6 +75,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
private var lightStatusBar: Boolean = false private var lightStatusBar: Boolean = false
private var lightNavigationBar: Boolean = false private var lightNavigationBar: Boolean = false
private var navigationBarColorAnimator: ValueAnimator? = null private var navigationBarColorAnimator: ValueAnimator? = null
private lateinit var queueAdapter: PlayingQueueAdapter
protected abstract fun createContentView(): View protected abstract fun createContentView(): View
private val panelState: Int private val panelState: Int
get() = bottomSheetBehavior.state get() = bottomSheetBehavior.state
@ -112,6 +117,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY) val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY)
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f)) dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
queueAdapter = PlayingQueueAdapter(this, ArrayList(), MusicPlayerRemote.position, R.layout.item_queue)
sheet2Container.adapter = queueAdapter
sheet2Container.layoutManager = LinearLayoutManager(this)
} }
override fun onResume() { override fun onResume() {
@ -270,6 +279,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
override fun onGlobalLayout() { override fun onGlobalLayout() {
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this) slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
hideBottomBar(false) hideBottomBar(false)
queueAdapter.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
} }
}) })
} // don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout } // don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout
@ -278,6 +288,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
override fun onQueueChanged() { override fun onQueueChanged() {
super.onQueueChanged() super.onQueueChanged()
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty()) hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
queueAdapter.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
} }
override fun onBackPressed() { override fun onBackPressed() {
@ -285,11 +296,14 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
} }
open fun handleBackPress(): Boolean { open fun handleBackPress(): Boolean {
if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed()) return true /*if (bottomSheetBehavior.peekHeight != 0 && playerFragment!!.onBackPressed()) return true
if (panelState == BottomSheetBehavior.STATE_EXPANDED) { if (panelState == BottomSheetBehavior.STATE_EXPANDED) {
collapsePanel() collapsePanel()
return true return true
} }*/
if (mainContent.consumeBackPress())
return true
return false return false
} }

View File

@ -19,9 +19,9 @@ import com.bumptech.glide.Glide
import java.util.ArrayList import java.util.ArrayList
class AlbumCoverPagerAdapter( class AlbumCoverPagerAdapter(
fm: FragmentManager, fragmentManager: FragmentManager,
private val dataSet: ArrayList<Song> private val dataSet: ArrayList<Song>
) : CustomFragmentStatePagerAdapter(fm) { ) : CustomFragmentStatePagerAdapter(fragmentManager) {
private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null
private var currentColorReceiverPosition = -1 private var currentColorReceiverPosition = -1

View File

@ -16,10 +16,7 @@ import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_album_cover.viewPager import kotlinx.android.synthetic.main.fragment_player_album_cover.viewPager
class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChangeListener { class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChangeListener {
private var callbacks: Callbacks? = null private var callbacks: Callbacks? = null
private var currentPosition: Int = 0 private var currentPosition: Int = 0
private val colorReceiver = object : AlbumCoverFragment.ColorReceiver { private val colorReceiver = object : AlbumCoverFragment.ColorReceiver {
@ -34,22 +31,24 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
val transformer = ParallaxPagerTransformer(R.id.player_image) val transformer = ParallaxPagerTransformer(R.id.player_image)
transformer.setSpeed(0.3f) transformer.setSpeed(0.3f)
viewPager.setPageTransformer(true, transformer) viewPager.setPageTransformer(true, transformer)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(
savedInstanceState: Bundle?): View? { inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_player_album_cover, container, false) return inflater.inflate(R.layout.fragment_player_album_cover, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewPager.addOnPageChangeListener(this) viewPager.addOnPageChangeListener(this)
//noinspection ConstantConditions val nowPlayingScreen = PreferenceUtil.getInstance(requireContext()).nowPlayingScreen
if (PreferenceUtil.getInstance(requireContext()).carouselEffect() && if (PreferenceUtil.getInstance(requireContext()).carouselEffect() &&
!((PreferenceUtil.getInstance(requireContext()).nowPlayingScreen == NowPlayingScreen.FULL) || !((nowPlayingScreen == NowPlayingScreen.FULL) || (nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
(PreferenceUtil.getInstance(requireContext()).nowPlayingScreen == NowPlayingScreen.ADAPTIVE) || (nowPlayingScreen == NowPlayingScreen.FIT))
|| (PreferenceUtil.getInstance(requireContext()).nowPlayingScreen == NowPlayingScreen.FIT))) { ) {
viewPager.clipToPadding = false viewPager.clipToPadding = false
viewPager.setPadding(40, 40, 40, 0) viewPager.setPadding(40, 40, 40, 0)
viewPager.pageMargin = 0 viewPager.pageMargin = 0
@ -79,7 +78,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
private fun updatePlayingQueue() { private fun updatePlayingQueue() {
viewPager.apply { viewPager.apply {
adapter = AlbumCoverPagerAdapter(fragmentManager!!, MusicPlayerRemote.playingQueue) adapter = AlbumCoverPagerAdapter(childFragmentManager, MusicPlayerRemote.playingQueue)
viewPager.adapter!!.notifyDataSetChanged() viewPager.adapter!!.notifyDataSetChanged()
viewPager.currentItem = MusicPlayerRemote.position viewPager.currentItem = MusicPlayerRemote.position
onPageSelected(MusicPlayerRemote.position) onPageSelected(MusicPlayerRemote.position)
@ -87,7 +86,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
} }
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
} }
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
@ -101,14 +99,10 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
} }
override fun onPageScrollStateChanged(state: Int) { override fun onPageScrollStateChanged(state: Int) {
} }
private fun notifyColorChange(color: Int) { private fun notifyColorChange(color: Int) {
if (callbacks != null) { callbacks?.onColorChanged(color)
callbacks!!.onColorChanged(color)
}
} }
fun setCallbacks(listener: Callbacks) { fun setCallbacks(listener: Callbacks) {
@ -119,16 +113,13 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
viewPager.setPageTransformer(false, null) viewPager.setPageTransformer(false, null)
} }
interface Callbacks { interface Callbacks {
fun onColorChanged(color: Int) fun onColorChanged(color: Int)
fun onFavoriteToggled() fun onFavoriteToggled()
} }
companion object { companion object {
val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName
} }

View File

@ -111,7 +111,7 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
} }
override fun setDark(color: Int) { override fun setDark(color: Int) {
val colorBg = ATHUtil.resolveColor(requireContext(), android.R.attr.colorBackground) val colorBg = ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)
if (ColorUtil.isColorLight(colorBg)) { if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(requireContext(), true) lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor = lastDisabledPlaybackControlsColor =

View File

@ -28,10 +28,10 @@ import com.bumptech.glide.request.animation.GlideAnimation
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) { abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
protected val defaultFooterColor: Int protected val defaultFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.colorSurface) get() = ATHUtil.resolveColor(getView().context, R.attr.colorControlNormal)
protected val albumArtistFooterColor: Int protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.colorSurface) get() = ATHUtil.resolveColor(getView().context, R.attr.colorControlNormal)
abstract fun onColorReady(color: Int) abstract fun onColorReady(color: Int)

View File

@ -14,40 +14,35 @@
package code.name.monkey.retromusic.views; package code.name.monkey.retromusic.views;
import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class WidthFitSquareLayout extends FrameLayout { public class WidthFitSquareLayout extends FrameLayout {
private boolean forceSquare = true;
public WidthFitSquareLayout(Context context) { public WidthFitSquareLayout(@NonNull final Context context) {
super(context); super(context);
} }
public WidthFitSquareLayout(Context context, AttributeSet attributeSet) { public WidthFitSquareLayout(@NonNull final Context context, @Nullable final AttributeSet attrs) {
super(context, attributeSet); super(context, attrs);
} }
public WidthFitSquareLayout(Context context, AttributeSet attributeSet, int i) { public WidthFitSquareLayout(@NonNull final Context context, @Nullable final AttributeSet attrs,
super(context, attributeSet, i); final int defStyleAttr) {
super(context, attrs, defStyleAttr);
} }
@TargetApi(21) public WidthFitSquareLayout(@NonNull final Context context, @Nullable final AttributeSet attrs,
public WidthFitSquareLayout(Context context, AttributeSet attributeSet, int i, int i2) { final int defStyleAttr,
super(context, attributeSet, i, i2); final int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
} }
public void forceSquare(boolean z) { @Override
this.forceSquare = z; protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
requestLayout(); super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
protected void onMeasure(int i, int i2) {
if (this.forceSquare) {
i2 = i;
}
super.onMeasure(i, i2);
} }
} }

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2020 Hemanth Savarala.
~
~ Licensed under the GNU General Public License v3
~
~ This is free software: you can redistribute it and/or modify it under
~ the terms of the GNU General Public License as published by
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/colorControlNormal" />
<corners android:radius="8dp" />
<size
android:width="72dp"
android:height="4dp" />
</shape>

View File

@ -4,10 +4,10 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/miniPlayerContent" android:id="@+id/miniPlayerContent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="@dimen/bottom_sheet_peek_1_height"
android:background="?android:attr/background" android:background="?attr/colorSurface"
android:clickable="true" android:clickable="true"
android:focusable="false" android:focusable="true"
android:transitionName="@string/transition_mini_player" android:transitionName="@string/transition_mini_player"
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">

View File

@ -3,29 +3,22 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:layout_gravity="center">
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareCardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_gravity="center"> android:layout_margin="12dp"
app:cardCornerRadius="8dp"
app:cardElevation="8dp">
<com.google.android.material.card.MaterialCardView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/player_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="16dp" android:scaleType="centerCrop"
app:cardCornerRadius="8dp" tools:ignore="ContentDescription,UnusedAttribute"
app:cardElevation="6dp"> tools:srcCompat="@tools:sample/backgrounds/scenic[5]" />
<androidx.appcompat.widget.AppCompatImageView </code.name.monkey.retromusic.views.WidthFitSquareCardView>
android:id="@+id/player_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription,UnusedAttribute"
tools:srcCompat="@tools:sample/backgrounds/scenic[5]" />
</com.google.android.material.card.MaterialCardView>
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
</FrameLayout> </FrameLayout>

View File

@ -26,6 +26,19 @@
<include layout="@layout/status_bar" /> <include layout="@layout/status_bar" />
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playerToolbar"
style="@style/Toolbar"
android:layout_gravity="bottom"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout>
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -50,18 +63,5 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:layout="@layout/fragment_material_playback_controls" /> tools:layout="@layout/fragment_material_playback_controls" />
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playerToolbar"
style="@style/Toolbar"
android:layout_gravity="bottom"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout>
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/miniPlayerContent" android:id="@+id/miniPlayerContent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="@dimen/bottom_sheet_peek_1_height"
android:background="?attr/colorSurface" android:background="?attr/colorSurface"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"

View File

@ -32,6 +32,19 @@
<include layout="@layout/status_bar" /> <include layout="@layout/status_bar" />
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playerToolbar"
style="@style/Toolbar"
android:layout_gravity="bottom"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout>
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:id="@+id/playerAlbumCoverContainer" android:id="@+id/playerAlbumCoverContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -58,19 +71,5 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:layout="@layout/fragment_player_playback_controls" /> tools:layout="@layout/fragment_player_playback_controls" />
</FrameLayout> </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playerToolbar"
style="@style/Toolbar"
android:layout_gravity="bottom"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout>
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <code.name.monkey.retromusic.MultiSheetView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainContent" android:id="@+id/mainContent"
@ -28,22 +28,95 @@
app:cardBackgroundColor="?attr/colorSurface" app:cardBackgroundColor="?attr/colorSurface"
app:cardCornerRadius="0dp" app:cardCornerRadius="0dp"
app:cardUseCompatPadding="false" app:cardUseCompatPadding="false"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior"
app:strokeWidth="0dp"> app:strokeWidth="0dp">
<FrameLayout <FrameLayout
android:id="@+id/playerFragmentContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:elevation="2dp"
app:behavior_peekHeight="@dimen/bottom_sheet_peek_1_height"
app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior">
<fragment <FrameLayout
android:id="@+id/miniPlayerFragment" android:id="@+id/playerFragmentContainer"
android:name="code.name.monkey.retromusic.fragments.MiniPlayerFragment" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="48dp" android:layout_marginBottom="@dimen/bottom_sheet_peek_2_height" />
tools:layout="@layout/fragment_mini_player" />
<fragment
android:id="@+id/miniPlayerFragment"
android:name="code.name.monkey.retromusic.fragments.MiniPlayerFragment"
android:layout_width="match_parent"
android:layout_height="48dp"
tools:layout="@layout/fragment_mini_player" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/sheet1Coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/sheet2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:elevation="2dp"
android:orientation="vertical"
app:behavior_peekHeight="@dimen/bottom_sheet_peek_2_height"
app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior">
<FrameLayout
android:id="@+id/sheet2PeekView"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_peek_2_height"
android:elevation="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<code.name.monkey.retromusic.views.StatusBarView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:srcCompat="@drawable/ic_keyboard_arrow_up_24dp"
app:tint="?attr/colorControlNormal" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sheet2Container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/extendedToolbar" />
<FrameLayout
android:id="@+id/extendedToolbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:elevation="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sheet2PeekView">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/collapseBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="14dp"
app:srcCompat="@drawable/ic_keyboard_backspace_black_24dp"
app:tint="?attr/colorControlNormal" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</FrameLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<code.name.monkey.retromusic.views.BottomNavigationBarTinted <code.name.monkey.retromusic.views.BottomNavigationBarTinted
@ -61,5 +134,4 @@
app:labelVisibilityMode="labeled" app:labelVisibilityMode="labeled"
app:menu="@menu/bottom_navigation_main" app:menu="@menu/bottom_navigation_main"
tools:layout_height="56dp" /> tools:layout_height="56dp" />
</code.name.monkey.retromusic.MultiSheetView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -46,4 +46,6 @@
<dimen name="button_margin_horizontal">16dp</dimen> <dimen name="button_margin_horizontal">16dp</dimen>
<dimen name="home_icon_padding">14dp</dimen> <dimen name="home_icon_padding">14dp</dimen>
<dimen name="button_corner">24dp</dimen> <dimen name="button_corner">24dp</dimen>
<dimen name="bottom_sheet_peek_1_height">56dp</dimen>
<dimen name="bottom_sheet_peek_2_height">32dp</dimen>
</resources> </resources>