Added Shuffle fab in songs, albums & artist tab
This commit is contained in:
parent
c80293f33a
commit
6e081f30c0
10 changed files with 90 additions and 5 deletions
|
@ -128,10 +128,8 @@ fun ExtendedFloatingActionButton.accentColor() {
|
||||||
fun FloatingActionButton.accentColor() {
|
fun FloatingActionButton.accentColor() {
|
||||||
val color = ThemeStore.accentColor(context)
|
val color = ThemeStore.accentColor(context)
|
||||||
val textColor = MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color))
|
val textColor = MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color))
|
||||||
val colorStateList = ColorStateList.valueOf(color)
|
backgroundTintList = ColorStateList.valueOf(color)
|
||||||
val textColorStateList = ColorStateList.valueOf(textColor)
|
imageTintList = ColorStateList.valueOf(textColor)
|
||||||
backgroundTintList = colorStateList
|
|
||||||
imageTintList = textColorStateList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MaterialButton.applyColor(color: Int) {
|
fun MaterialButton.applyColor(color: Int) {
|
||||||
|
|
|
@ -27,10 +27,12 @@ import code.name.monkey.retromusic.adapter.album.AlbumAdapter
|
||||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||||
import code.name.monkey.retromusic.fragments.ReloadType
|
import code.name.monkey.retromusic.fragments.ReloadType
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
||||||
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder
|
import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder
|
||||||
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
|
||||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
|
@ -65,6 +67,20 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_albums
|
get() = R.string.no_albums
|
||||||
|
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun onShuffleClicked() {
|
||||||
|
libraryViewModel.getAlbums().value?.let {
|
||||||
|
MusicPlayerRemote.setShuffleMode(MusicService.SHUFFLE_MODE_NONE)
|
||||||
|
MusicPlayerRemote.openQueue(
|
||||||
|
queue = it.shuffled().flatMap { album -> album.songs },
|
||||||
|
startPosition = 0,
|
||||||
|
startPlaying = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun createLayoutManager(): GridLayoutManager {
|
override fun createLayoutManager(): GridLayoutManager {
|
||||||
return GridLayoutManager(requireActivity(), getGridSize())
|
return GridLayoutManager(requireActivity(), getGridSize())
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,13 @@ import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
|
||||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||||
import code.name.monkey.retromusic.fragments.ReloadType
|
import code.name.monkey.retromusic.fragments.ReloadType
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
||||||
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder
|
import code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder
|
||||||
import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener
|
import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener
|
||||||
import code.name.monkey.retromusic.interfaces.IArtistClickListener
|
import code.name.monkey.retromusic.interfaces.IArtistClickListener
|
||||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import code.name.monkey.retromusic.util.RetroUtil
|
import code.name.monkey.retromusic.util.RetroUtil
|
||||||
|
@ -62,9 +64,24 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
||||||
|
|
||||||
override val titleRes: Int
|
override val titleRes: Int
|
||||||
get() = R.string.artists
|
get() = R.string.artists
|
||||||
|
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_artists
|
get() = R.string.no_artists
|
||||||
|
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun onShuffleClicked() {
|
||||||
|
libraryViewModel.getArtists().value?.let {
|
||||||
|
MusicPlayerRemote.setShuffleMode(MusicService.SHUFFLE_MODE_NONE)
|
||||||
|
MusicPlayerRemote.openQueue(
|
||||||
|
queue = it.shuffled().flatMap { artist -> artist.songs },
|
||||||
|
startPosition = 0,
|
||||||
|
startPlaying = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setSortOrder(sortOrder: String) {
|
override fun setSortOrder(sortOrder: String) {
|
||||||
libraryViewModel.forceReload(ReloadType.Artists)
|
libraryViewModel.forceReload(ReloadType.Artists)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.view.doOnPreDraw
|
import androidx.core.view.doOnPreDraw
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
@ -30,6 +31,7 @@ import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.databinding.FragmentMainRecyclerBinding
|
import code.name.monkey.retromusic.databinding.FragmentMainRecyclerBinding
|
||||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
|
||||||
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
|
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
|
||||||
|
import code.name.monkey.retromusic.extensions.accentColor
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.util.DensityUtil
|
import code.name.monkey.retromusic.util.DensityUtil
|
||||||
import code.name.monkey.retromusic.util.ThemedFastScroller.create
|
import code.name.monkey.retromusic.util.ThemedFastScroller.create
|
||||||
|
@ -45,6 +47,8 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
protected var adapter: A? = null
|
protected var adapter: A? = null
|
||||||
protected var layoutManager: LM? = null
|
protected var layoutManager: LM? = null
|
||||||
|
val shuffleButton get() = binding.shuffleButton
|
||||||
|
abstract val isShuffleVisible: Boolean
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
@ -60,6 +64,30 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
binding.appBarLayout.statusBarForeground =
|
binding.appBarLayout.statusBarForeground =
|
||||||
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
|
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
|
||||||
|
|
||||||
|
// Add listeners when shuffle is visible
|
||||||
|
if (isShuffleVisible) {
|
||||||
|
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
if (dy > 0) {
|
||||||
|
binding.shuffleButton.hide()
|
||||||
|
} else if (dy < 0) {
|
||||||
|
binding.shuffleButton.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
binding.shuffleButton.setOnClickListener {
|
||||||
|
onShuffleClicked()
|
||||||
|
}
|
||||||
|
binding.shuffleButton.accentColor()
|
||||||
|
} else {
|
||||||
|
binding.shuffleButton.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onShuffleClicked() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toolbar(): Toolbar {
|
fun toolbar(): Toolbar {
|
||||||
|
|
|
@ -82,6 +82,9 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_genres
|
get() = R.string.no_genres
|
||||||
|
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val TAG: String = GenresFragment::class.java.simpleName
|
val TAG: String = GenresFragment::class.java.simpleName
|
||||||
|
|
|
@ -48,9 +48,13 @@ class PlaylistsFragment :
|
||||||
|
|
||||||
override val titleRes: Int
|
override val titleRes: Int
|
||||||
get() = R.string.playlists
|
get() = R.string.playlists
|
||||||
|
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_playlists
|
get() = R.string.no_playlists
|
||||||
|
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
override fun createLayoutManager(): GridLayoutManager {
|
override fun createLayoutManager(): GridLayoutManager {
|
||||||
return GridLayoutManager(requireContext(), getGridSize())
|
return GridLayoutManager(requireContext(), getGridSize())
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ class PlayingQueueFragment : AbsRecyclerViewFragment<PlayingQueueAdapter, Linear
|
||||||
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
|
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
|
||||||
override val titleRes: Int
|
override val titleRes: Int
|
||||||
get() = R.string.now_playing_queue
|
get() = R.string.now_playing_queue
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import code.name.monkey.retromusic.adapter.song.SongAdapter
|
||||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||||
import code.name.monkey.retromusic.fragments.ReloadType
|
import code.name.monkey.retromusic.fragments.ReloadType
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
|
||||||
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.SongSortOrder
|
import code.name.monkey.retromusic.helper.SortOrder.SongSortOrder
|
||||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||||
|
@ -62,6 +63,13 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_songs
|
get() = R.string.no_songs
|
||||||
|
|
||||||
|
override val isShuffleVisible: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun onShuffleClicked() {
|
||||||
|
libraryViewModel.getSongs().value?.let { MusicPlayerRemote.openAndShuffleQueue(it, true) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun createLayoutManager(): GridLayoutManager {
|
override fun createLayoutManager(): GridLayoutManager {
|
||||||
return GridLayoutManager(requireActivity(), getGridSize()).apply {
|
return GridLayoutManager(requireActivity(), getGridSize()).apply {
|
||||||
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||||
|
|
|
@ -301,7 +301,7 @@ object MusicPlayerRemote : KoinComponent {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setShuffleMode(shuffleMode: Int): Boolean {
|
fun setShuffleMode(shuffleMode: Int): Boolean {
|
||||||
if (musicService != null) {
|
if (musicService != null) {
|
||||||
musicService!!.shuffleMode = shuffleMode
|
musicService!!.shuffleMode = shuffleMode
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -78,4 +78,13 @@
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/shuffle_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|right"
|
||||||
|
app:srcCompat="@drawable/ic_shuffle"
|
||||||
|
android:layout_marginBottom="116dp"
|
||||||
|
android:layout_marginHorizontal="16dp"/>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
Loading…
Reference in a new issue