Move detail controls to Toolbar
Move the play/shuffle buttons from the header of the DetailFragments to their Toolbar, it makes far more sense for them to be there honestly.
This commit is contained in:
parent
d01aa3ea4a
commit
c4c115274b
27 changed files with 147 additions and 192 deletions
|
@ -55,16 +55,30 @@ class AlbumDetailFragment : Fragment() {
|
|||
binding.playbackModel = playbackModel
|
||||
binding.album = detailModel.currentAlbum.value!!
|
||||
|
||||
binding.albumToolbar.apply {
|
||||
setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
|
||||
setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.action_shuffle -> playbackModel.play(
|
||||
detailModel.currentAlbum.value!!,
|
||||
true
|
||||
)
|
||||
R.id.action_play -> playbackModel.play(detailModel.currentAlbum.value!!, false)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.albumSongRecycler.apply {
|
||||
adapter = songAdapter
|
||||
applyDivider()
|
||||
setHasFixedSize(true)
|
||||
}
|
||||
|
||||
binding.albumToolbar.setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
|
||||
// Don't enable the sort button if there's only one song [or less]
|
||||
if (detailModel.currentAlbum.value!!.numSongs < 2) {
|
||||
binding.albumSortButton.disable(requireContext())
|
||||
|
@ -84,16 +98,6 @@ class AlbumDetailFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
|
||||
// Observe playback model to update the play button
|
||||
// TODO: Make these icons animated
|
||||
playbackModel.currentMode.observe(viewLifecycleOwner) {
|
||||
updatePlayButton(it, binding)
|
||||
}
|
||||
|
||||
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
||||
updatePlayButton(playbackModel.currentMode.value!!, binding)
|
||||
}
|
||||
|
||||
// If the album was shown directly from LibraryFragment, Then enable the ability to
|
||||
// navigate upwards to the parent artist
|
||||
if (args.enableParentNav) {
|
||||
|
@ -118,34 +122,4 @@ class AlbumDetailFragment : Fragment() {
|
|||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
// Update the play button depending on the current playback status
|
||||
// If playing this album -> Make button show media controls
|
||||
// If not playing this album -> Make button update playback to the artist
|
||||
private fun updatePlayButton(
|
||||
mode: PlaybackMode,
|
||||
binding: FragmentAlbumDetailBinding
|
||||
) {
|
||||
playbackModel.currentParent.value?.let { parent ->
|
||||
if (mode == PlaybackMode.IN_ALBUM &&
|
||||
parent.id == detailModel.currentAlbum.value!!.id
|
||||
) {
|
||||
if (playbackModel.isPlaying.value!!) {
|
||||
binding.albumPlay.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
binding.albumPlay.setImageResource(R.drawable.ic_play)
|
||||
}
|
||||
|
||||
binding.albumPlay.setOnClickListener {
|
||||
playbackModel.invertPlayingStatus()
|
||||
}
|
||||
} else {
|
||||
binding.albumPlay.setImageResource(R.drawable.ic_play)
|
||||
|
||||
binding.albumPlay.setOnClickListener {
|
||||
playbackModel.play(detailModel.currentAlbum.value!!, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ import org.oxycblt.auxio.R
|
|||
import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding
|
||||
import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.playback.PlaybackMode
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.theme.applyDivider
|
||||
import org.oxycblt.auxio.theme.disable
|
||||
|
||||
class ArtistDetailFragment : Fragment() {
|
||||
|
||||
private val args: ArtistDetailFragmentArgs by navArgs()
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
|
@ -60,8 +58,22 @@ class ArtistDetailFragment : Fragment() {
|
|||
binding.playbackModel = playbackModel
|
||||
binding.artist = detailModel.currentArtist.value!!
|
||||
|
||||
binding.artistToolbar.setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
binding.artistToolbar.apply {
|
||||
setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
|
||||
setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.action_shuffle -> playbackModel.play(
|
||||
detailModel.currentArtist.value!!,
|
||||
true
|
||||
)
|
||||
R.id.action_play -> playbackModel.play(detailModel.currentArtist.value!!, false)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the sort button if there is only one album [Or less]
|
||||
|
@ -89,49 +101,11 @@ class ArtistDetailFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
|
||||
playbackModel.currentMode.observe(viewLifecycleOwner) {
|
||||
updatePlayButton(it, binding)
|
||||
}
|
||||
|
||||
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
||||
updatePlayButton(playbackModel.currentMode.value!!, binding)
|
||||
}
|
||||
|
||||
Log.d(this::class.simpleName, "Fragment created.")
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
// Update the play button depending on the current playback status
|
||||
// If playing this artist -> Make button show media controls
|
||||
// If not playing this artist -> Make button update playback to the artist
|
||||
private fun updatePlayButton(
|
||||
mode: PlaybackMode,
|
||||
binding: FragmentArtistDetailBinding
|
||||
) {
|
||||
playbackModel.currentParent.value?.let { parent ->
|
||||
if (mode == PlaybackMode.IN_ARTIST &&
|
||||
parent.id == detailModel.currentArtist.value!!.id
|
||||
) {
|
||||
if (playbackModel.isPlaying.value!!) {
|
||||
binding.artistPlay.setImageResource(R.drawable.ic_pause)
|
||||
} else {
|
||||
binding.artistPlay.setImageResource(R.drawable.ic_play)
|
||||
}
|
||||
|
||||
binding.artistPlay.setOnClickListener {
|
||||
playbackModel.invertPlayingStatus()
|
||||
}
|
||||
} else {
|
||||
binding.artistPlay.setImageResource(R.drawable.ic_play)
|
||||
|
||||
binding.artistPlay.setOnClickListener {
|
||||
playbackModel.play(detailModel.currentAlbum.value!!, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ import org.oxycblt.auxio.recycler.SortMode
|
|||
|
||||
// ViewModel for the Detail Fragments.
|
||||
// TODO:
|
||||
// - Implement a system where the Toolbar will update with the info [And Media Controls] when
|
||||
// the main info of the detail fragment is removed.
|
||||
// - Implement a system where the Toolbar will update with some infowhen
|
||||
// the main detail header is obscured.
|
||||
class DetailViewModel : ViewModel() {
|
||||
private var mIsNavigating = false
|
||||
val isNavigating: Boolean get() = mIsNavigating
|
||||
|
|
|
@ -9,9 +9,11 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentGenreDetailBinding
|
||||
import org.oxycblt.auxio.detail.adapters.DetailArtistAdapter
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.theme.applyDivider
|
||||
import org.oxycblt.auxio.theme.disable
|
||||
|
||||
|
@ -19,6 +21,7 @@ class GenreDetailFragment : Fragment() {
|
|||
|
||||
private val args: GenreDetailFragmentArgs by navArgs()
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -55,8 +58,22 @@ class GenreDetailFragment : Fragment() {
|
|||
binding.detailModel = detailModel
|
||||
binding.genre = detailModel.currentGenre.value
|
||||
|
||||
binding.genreToolbar.setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
binding.genreToolbar.apply {
|
||||
setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
|
||||
setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.action_shuffle -> playbackModel.play(
|
||||
detailModel.currentGenre.value!!,
|
||||
true
|
||||
)
|
||||
R.id.action_play -> playbackModel.play(detailModel.currentGenre.value!!, false)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the sort button if there is only one artist [Or less]
|
||||
|
|
|
@ -21,7 +21,7 @@ class LibraryViewModel : ViewModel() {
|
|||
val searchHasFocus: Boolean get() = mSearchHasFocus
|
||||
|
||||
// TODO: Move these to prefs when they're added
|
||||
private val mShowMode = MutableLiveData(ShowMode.SHOW_ARTISTS)
|
||||
private val mShowMode = MutableLiveData(ShowMode.SHOW_GENRES)
|
||||
val showMode: LiveData<ShowMode> get() = mShowMode
|
||||
|
||||
private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN)
|
||||
|
|
|
@ -38,7 +38,7 @@ class CompactPlaybackFragment : Fragment() {
|
|||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
|
||||
// Put a placeholder song in the binding & hide the playback fragment initially,
|
||||
// as for some reason the attach event doesn't register anymore w/LiveData
|
||||
// just in case.
|
||||
binding.song = MusicStore.getInstance().songs[0]
|
||||
binding.playbackModel = playbackModel
|
||||
|
||||
|
@ -59,7 +59,6 @@ class CompactPlaybackFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Fix the thing where the icons will animate on startup
|
||||
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
||||
if (playbackModel.canAnimate) {
|
||||
if (it) {
|
||||
|
|
|
@ -46,7 +46,9 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
|
||||
// --- UI SETUP ---
|
||||
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.playbackModel = playbackModel
|
||||
binding.song = playbackModel.currentSong.value!!
|
||||
|
||||
binding.playbackToolbar.setNavigationOnClickListener {
|
||||
findNavController().navigateUp()
|
||||
|
@ -54,7 +56,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
|||
|
||||
// Make marquee scroll work
|
||||
binding.playbackSong.isSelected = true
|
||||
|
||||
binding.playbackSeekBar.setOnSeekBarChangeListener(this)
|
||||
|
||||
// --- VIEWMODEL SETUP --
|
||||
|
|
|
@ -5,5 +5,5 @@ package org.oxycblt.auxio.playback
|
|||
// IN_ARTIST -> Play from the songs of the artist
|
||||
// IN_ALBUM -> Play from the songs of the album
|
||||
enum class PlaybackMode {
|
||||
IN_ARTIST, IN_ALBUM, ALL_SONGS;
|
||||
IN_ARTIST, IN_GENRE, IN_ALBUM, ALL_SONGS;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.lifecycle.ViewModel
|
|||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.toDuration
|
||||
|
@ -63,6 +64,15 @@ class PlaybackViewModel : ViewModel() {
|
|||
|
||||
// Update the current song while changing the queue mode.
|
||||
fun update(song: Song, mode: PlaybackMode) {
|
||||
|
||||
// Auxio doesn't support playing songs while swapping the mode to GENRE, as genres
|
||||
// are bound to artists, not songs.
|
||||
if (mode == PlaybackMode.IN_GENRE) {
|
||||
Log.e(this::class.simpleName, "Auxio cant play songs with the mode of IN_GENRE.")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Log.d(this::class.simpleName, "Updating song to ${song.name} and mode to $mode")
|
||||
|
||||
val musicStore = MusicStore.getInstance()
|
||||
|
@ -75,12 +85,14 @@ class PlaybackViewModel : ViewModel() {
|
|||
PlaybackMode.ALL_SONGS -> musicStore.songs.toMutableList()
|
||||
PlaybackMode.IN_ARTIST -> song.album.artist.songs
|
||||
PlaybackMode.IN_ALBUM -> song.album.songs
|
||||
PlaybackMode.IN_GENRE -> error("what")
|
||||
}
|
||||
|
||||
mCurrentParent.value = when (mode) {
|
||||
PlaybackMode.ALL_SONGS -> null
|
||||
PlaybackMode.IN_ARTIST -> song.album.artist
|
||||
PlaybackMode.IN_ALBUM -> song.album
|
||||
PlaybackMode.IN_GENRE -> error("what")
|
||||
}
|
||||
|
||||
if (mIsShuffling.value!!) {
|
||||
|
@ -92,6 +104,7 @@ class PlaybackViewModel : ViewModel() {
|
|||
mCurrentIndex.value = mQueue.value!!.indexOf(song)
|
||||
}
|
||||
|
||||
// Play some parent music model, whether that being albums/artists/genres.
|
||||
fun play(album: Album, isShuffled: Boolean) {
|
||||
Log.d(this::class.simpleName, "Playing album ${album.name}")
|
||||
|
||||
|
@ -132,6 +145,26 @@ class PlaybackViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun play(genre: Genre, isShuffled: Boolean) {
|
||||
Log.d(this::class.simpleName, "Playing genre ${genre.name}")
|
||||
|
||||
val songs = orderSongsInGenre(genre)
|
||||
|
||||
updatePlayback(songs[0])
|
||||
|
||||
mQueue.value = songs
|
||||
mCurrentIndex.value = 0
|
||||
mCurrentParent.value = genre
|
||||
mIsShuffling.value = isShuffled
|
||||
mCurrentMode.value = PlaybackMode.IN_GENRE
|
||||
|
||||
if (mIsShuffling.value!!) {
|
||||
genShuffle(false)
|
||||
} else {
|
||||
resetShuffle()
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current duration using a SeekBar progress
|
||||
fun updateCurrentDurationWithProgress(progress: Int) {
|
||||
mCurrentDuration.value = progress.toLong()
|
||||
|
@ -232,6 +265,7 @@ class PlaybackViewModel : ViewModel() {
|
|||
mQueue.value = when (mCurrentMode.value!!) {
|
||||
PlaybackMode.IN_ARTIST -> orderSongsInArtist(mCurrentParent.value as Artist)
|
||||
PlaybackMode.IN_ALBUM -> orderSongsInAlbum(mCurrentParent.value as Album)
|
||||
PlaybackMode.IN_GENRE -> orderSongsInGenre(mCurrentParent.value as Genre)
|
||||
PlaybackMode.ALL_SONGS -> MusicStore.getInstance().songs.toMutableList()
|
||||
}
|
||||
|
||||
|
@ -246,8 +280,22 @@ class PlaybackViewModel : ViewModel() {
|
|||
private fun orderSongsInArtist(artist: Artist): MutableList<Song> {
|
||||
val final = mutableListOf<Song>()
|
||||
|
||||
artist.albums.sortedByDescending { it.year }.forEach {
|
||||
final.addAll(it.songs.sortedBy { it.track })
|
||||
artist.albums.sortedByDescending { it.year }.forEach { album ->
|
||||
final.addAll(album.songs.sortedBy { it.track })
|
||||
}
|
||||
|
||||
return final
|
||||
}
|
||||
|
||||
private fun orderSongsInGenre(genre: Genre): MutableList<Song> {
|
||||
val final = mutableListOf<Song>()
|
||||
|
||||
genre.artists.sortedWith(
|
||||
compareBy(String.CASE_INSENSITIVE_ORDER) { it.name }
|
||||
).forEach { artist ->
|
||||
artist.albums.sortedByDescending { it.year }.forEach { album ->
|
||||
final.addAll(album.songs.sortedBy { it.track })
|
||||
}
|
||||
}
|
||||
|
||||
return final
|
||||
|
|
|
@ -82,7 +82,7 @@ class AlbumViewHolder private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Add indicators to song recycler items when they're being played.
|
||||
// TODO: Add indicators to song recycler items when they're being played?
|
||||
|
||||
class SongViewHolder private constructor(
|
||||
doOnClick: (Song) -> Unit,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M 5.88,7.06 12,13.166667 18.12,7.06 20,8.94 l -8,8 -8,-8 z" />
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="m 7.5,6 h 3 v 12 h -3 z m 9,0 h -3 v 12 h 3 z" />
|
||||
|
|
|
@ -9,7 +9,6 @@ https://github.com/ashutoshgngwr/noice
|
|||
<vector
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:alpha="1"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
|
@ -19,21 +18,20 @@ https://github.com/ashutoshgngwr/noice
|
|||
android:pivotY="12">
|
||||
|
||||
<path
|
||||
android:name="play_upper"
|
||||
android:name="pause_right"
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M8.25,6L8.25,12L18.75,12L18.75,12Z" />
|
||||
android:pathData="M 22.677734 18.898438 L 22.677734 71.810547 L 37.794922 71.810547 L 37.794922 18.898438 L 22.677734 18.898438 z" />
|
||||
|
||||
<path
|
||||
android:name="play_lower"
|
||||
android:name="pause_left"
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M8.25,18L8.25,12L18.75,12L18.75,12Z" />
|
||||
android:pathData="M 52.914062 18.898438 L 52.914062 71.810547 L 68.03125 71.810547 L 68.03125 18.898438 L 52.914062 18.898438 z " />
|
||||
|
||||
</group>
|
||||
|
||||
</vector>
|
||||
</aapt:attr>
|
||||
|
||||
<target android:name="play_upper">
|
||||
<target android:name="pause_right">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
|
@ -47,7 +45,7 @@ https://github.com/ashutoshgngwr/noice
|
|||
</aapt:attr>
|
||||
</target>
|
||||
|
||||
<target android:name="play_lower">
|
||||
<target android:name="pause_left">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/background">
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M8.25,6L8.25,12L18.75,12L18.75,12ZM8.25,18L8.25,12L18.75,12L18.75,12Z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10.59,9.17L5.41,4 4,5.41l5.17,5.17 1.42,-1.41zM14.5,4l2.04,2.04L4,18.59 5.41,20 17.96,7.46 20,9.5L20,4h-5.5zM14.83,13.41l-1.41,1.41 3.13,3.13L14.5,20L20,20v-5.5l-2.04,2.04 -3.13,-3.13z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10.59,9.17L5.41,4 4,5.41l5.17,5.17 1.42,-1.41zM14.5,4l2.04,2.04L4,18.59 5.41,20 17.96,7.46 20,9.5L20,4h-5.5zM14.83,13.41l-1.41,1.41 3.13,3.13L14.5,20L20,20v-5.5l-2.04,2.04 -3.13,-3.13z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/control_color">
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" />
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorPrimary">
|
||||
|
||||
<path
|
||||
android:pathData="M6.542 18q-1.508-0.006-2.595-0.716-1.082-0.711-1.667-2.06-0.578-1.348-0.573-3.244 0-1.89 0.58-3.221 0.584-1.331 1.665-2.025 1.088-0.7 2.59-0.7 1.503 0 2.584 0.7 1.088 0.7 1.673 2.03 0.584 1.326 0.578 3.216 0 1.902-0.584 3.25-0.579 1.348-1.66 2.06Q8.05 18 6.542 18zm0-2.025q1.03 0 1.643-0.999 0.614-0.998 0.608-2.996 0-1.314-0.28-2.188-0.275-0.875-0.784-1.315-0.503-0.44-1.187-0.44-1.023 0-1.637 0.987-0.614 0.988-0.62 2.957 0 1.33 0.276 2.222 0.28 0.886 0.789 1.332 0.508 0.44 1.193 0.44zM17.51 6q0.924 0 1.777 0.3 0.86 0.293 1.532 0.953 0.679 0.66 1.07 1.749 0.398 1.083 0.404 2.668-0.006 1.472-0.351 2.629-0.34 1.15-0.976 1.958-0.638 0.806-1.538 1.23-0.895 0.417-2.005 0.417-1.199 0-2.117-0.446-0.918-0.45-1.479-1.224-0.555-0.779-0.672-1.749h2.496q0.146 0.632 0.614 0.982 0.468 0.344 1.158 0.344 1.169 0 1.777-0.982 0.608-0.987 0.614-2.702h-0.082Q19.463 12.635 19.007 13q-0.456 0.362-1.046 0.559-0.585 0.197-1.246 0.197-1.058 0-1.894-0.48-0.83-0.479-1.31-1.32-0.479-0.846-0.473-1.929-0.006-1.173 0.555-2.082 0.562-0.914 1.567-1.433Q16.172 5.994 17.51 6zm0.018 1.918q-0.59 0-1.053 0.271Q16.02 8.46 15.75 8.923q-0.263 0.462-0.257 1.038-0.006 0.575 0.252 1.032 0.263 0.457 0.719 0.728 0.456 0.265 1.04 0.265 0.439 0 0.807-0.158 0.374-0.158 0.65-0.434 0.28-0.282 0.438-0.65 0.158-0.372 0.163-0.795-0.005-0.558-0.269-1.02-0.263-0.463-0.725-0.734-0.461-0.277-1.04-0.277z"
|
||||
android:strokeWidth="0.404319"
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:menu="@menu/menu_detail"
|
||||
app:popupTheme="@style/AppThemeOverlay.Popup"
|
||||
app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
|
||||
app:navigationIcon="@drawable/ic_back"
|
||||
app:title="@string/title_library_fragment" />
|
||||
|
@ -103,42 +105,6 @@
|
|||
app:layout_constraintTop_toBottomOf="@+id/album_artist"
|
||||
tools:text="2020 / 10 Songs / 16:16" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/album_play"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/margin_tiny"
|
||||
android:layout_marginEnd="@dimen/margin_tiny"
|
||||
android:tint="@color/background"
|
||||
android:background="@drawable/ui_circular_button"
|
||||
android:backgroundTint="?android:attr/colorPrimary"
|
||||
android:contentDescription="@string/description_play"
|
||||
android:src="@drawable/ic_play"
|
||||
android:onClick="@{() -> playbackModel.play(album, false)}"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/album_details"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toStartOf="@+id/album_shuffle"
|
||||
app:layout_constraintTop_toTopOf="@+id/album_artist" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/album_shuffle"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="@dimen/margin_medium"
|
||||
android:layout_marginTop="@dimen/margin_tiny"
|
||||
android:background="@drawable/ui_circular_button"
|
||||
android:backgroundTint="?android:attr/colorPrimary"
|
||||
android:contentDescription="@string/description_play"
|
||||
android:onClick="@{() -> playbackModel.play(album, true)}"
|
||||
android:src="@drawable/ic_shuffle"
|
||||
android:tint="@color/background"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/album_details"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/album_artist" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/album_song_header"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:popupTheme="@style/AppThemeOverlay.Popup"
|
||||
app:menu="@menu/menu_detail"
|
||||
app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
|
||||
app:navigationIcon="@drawable/ic_back"
|
||||
app:title="@string/title_library_fragment" />
|
||||
|
@ -98,43 +100,6 @@
|
|||
app:layout_constraintTop_toBottomOf="@+id/artist_genre"
|
||||
tools:text="2 Albums, 20 Songs" />
|
||||
|
||||
<!-- TODO: Improve these two buttons so that they dont look as cluttered -->
|
||||
<ImageButton
|
||||
android:id="@+id/artist_play"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/margin_tiny"
|
||||
android:layout_marginEnd="@dimen/margin_tiny"
|
||||
android:tint="@color/background"
|
||||
android:background="@drawable/ui_circular_button"
|
||||
android:backgroundTint="?android:attr/colorPrimary"
|
||||
android:contentDescription="@string/description_play"
|
||||
android:src="@drawable/ic_play"
|
||||
android:onClick="@{() -> playbackModel.play(artist, false)}"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toStartOf="@+id/artist_shuffle"
|
||||
app:layout_constraintTop_toTopOf="@+id/artist_genre" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/artist_shuffle"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="@dimen/margin_medium"
|
||||
android:layout_marginTop="@dimen/margin_tiny"
|
||||
android:background="@drawable/ui_circular_button"
|
||||
android:backgroundTint="?android:attr/colorPrimary"
|
||||
android:contentDescription="@string/description_play"
|
||||
android:onClick="@{() -> playbackModel.play(artist, true)}"
|
||||
android:src="@drawable/ic_shuffle"
|
||||
android:tint="@color/background"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/artist_genre" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/artist_album_header"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:elevation="@dimen/elevation_normal"
|
||||
app:popupTheme="@style/AppThemeOverlay.Popup"
|
||||
app:menu="@menu/menu_detail"
|
||||
app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
|
||||
app:navigationIcon="@drawable/ic_back"
|
||||
app:title="@string/title_library_fragment" />
|
||||
|
|
13
app/src/main/res/menu/menu_detail.xml
Normal file
13
app/src/main/res/menu/menu_detail.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_shuffle"
|
||||
android:icon="@drawable/ic_shuffle"
|
||||
android:title="@string/label_shuffle"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_play"
|
||||
android:title="@string/label_play"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
|
@ -6,6 +6,7 @@
|
|||
<item name="android:statusBarColor">@android:color/black</item>
|
||||
<item name="android:fontFamily">@font/inter</item>
|
||||
<item name="android:textCursorDrawable">@drawable/ui_cursor</item>
|
||||
<item name="android:colorControlNormal">@color/control_color</item>
|
||||
</style>
|
||||
|
||||
<!-- Toolbar Themes -->
|
||||
|
|
Loading…
Reference in a new issue