Added MD3 playing theme
This commit is contained in:
parent
ae13590204
commit
7debeb13c0
13 changed files with 771 additions and 0 deletions
|
@ -67,6 +67,7 @@
|
|||
<h2>v5.8.3</h2>
|
||||
<h3>What's New</h3>
|
||||
<ul>
|
||||
<li>Added a new MD3 now playing theme</li>
|
||||
<li>Swipe down to dismiss Mini player</li>
|
||||
<li>Add support for Just Black with Material You</li>
|
||||
</ul>
|
||||
|
|
|
@ -49,6 +49,7 @@ import code.name.monkey.retromusic.fragments.player.flat.FlatPlayerFragment
|
|||
import code.name.monkey.retromusic.fragments.player.full.FullPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.gradient.GradientPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.material.MaterialFragment
|
||||
import code.name.monkey.retromusic.fragments.player.md3.MD3PlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.peek.PeekPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.plain.PlainPlayerFragment
|
||||
|
@ -457,6 +458,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
Peek -> PeekPlayerFragment()
|
||||
Circle -> CirclePlayerFragment()
|
||||
Classic -> ClassicPlayerFragment()
|
||||
MD3 -> MD3PlayerFragment()
|
||||
else -> PlayerFragment()
|
||||
} // must implement AbsPlayerFragment
|
||||
supportFragmentManager.commit {
|
||||
|
|
|
@ -292,6 +292,9 @@ fun Context.accentColorVariant(): Int {
|
|||
inline val @receiver:ColorInt Int.isColorLight
|
||||
get() = ColorUtil.isColorLight(this)
|
||||
|
||||
inline val @receiver:ColorInt Int.lightColor
|
||||
get() = ColorUtil.withAlpha(this, 0.5F)
|
||||
|
||||
inline val @receiver:ColorInt Int.lighterColor
|
||||
get() = ColorUtil.lightenColor(this)
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -163,6 +164,23 @@ fun BottomSheetBehavior<*>.peekHeightAnimate(value: Int): Animator {
|
|||
}
|
||||
}
|
||||
|
||||
fun MaterialCardView.animateRadius(cornerRadius: Float, pause: Boolean = true) {
|
||||
ValueAnimator.ofFloat(radius, cornerRadius).apply {
|
||||
addUpdateListener { radius = animatedValue as Float }
|
||||
start()
|
||||
}
|
||||
ValueAnimator.ofInt(measuredWidth, if (pause) (height * 1.5).toInt() else height).apply {
|
||||
addUpdateListener {
|
||||
updateLayoutParams<ViewGroup.LayoutParams> { width = animatedValue as Int }
|
||||
}
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
fun MaterialCardView.animateToCircle() {
|
||||
animateRadius(measuredHeight / 2F, pause = false)
|
||||
}
|
||||
|
||||
fun View.focusAndShowKeyboard() {
|
||||
/**
|
||||
* This is to be called when the window already has focus.
|
||||
|
|
|
@ -39,6 +39,7 @@ enum class NowPlayingScreen constructor(
|
|||
Full(R.string.full, R.drawable.np_full, 2, AlbumCoverStyle.Full),
|
||||
Gradient(R.string.gradient, R.drawable.np_gradient, 17, AlbumCoverStyle.Full),
|
||||
Material(R.string.material, R.drawable.np_material, 11, AlbumCoverStyle.Normal),
|
||||
MD3(R.string.md3, R.drawable.np_normal, 18, AlbumCoverStyle.Normal),
|
||||
Normal(R.string.normal, R.drawable.np_normal, 0, AlbumCoverStyle.Normal),
|
||||
Peek(R.string.peek, R.drawable.np_peek, 14, AlbumCoverStyle.Normal),
|
||||
Plain(R.string.plain, R.drawable.np_plain, 3, AlbumCoverStyle.Normal),
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarla.
|
||||
*
|
||||
* 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.fragments.player.md3
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.ImageButton
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
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.databinding.FragmentMd3PlayerPlaybackControlsBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.goToAlbum
|
||||
import code.name.monkey.retromusic.fragments.base.goToArtist
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
|
||||
class MD3PlaybackControlsFragment :
|
||||
AbsPlayerControlsFragment(R.layout.fragment_md3_player_playback_controls) {
|
||||
|
||||
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
|
||||
private var _binding: FragmentMd3PlayerPlaybackControlsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override val progressSlider: SeekBar
|
||||
get() = binding.progressSlider
|
||||
|
||||
override val shuffleButton: ImageButton
|
||||
get() = binding.shuffleButton
|
||||
|
||||
override val repeatButton: ImageButton
|
||||
get() = binding.repeatButton
|
||||
|
||||
override val nextButton: ImageButton
|
||||
get() = binding.nextButton
|
||||
|
||||
override val previousButton: ImageButton
|
||||
get() = binding.previousButton
|
||||
|
||||
override val songTotalTime: TextView
|
||||
get() = binding.songTotalTime
|
||||
|
||||
override val songCurrentProgress: TextView
|
||||
get() = binding.songCurrentProgress
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentMd3PlayerPlaybackControlsBinding.bind(view)
|
||||
setUpMusicControllers()
|
||||
binding.playPauseButton.setOnClickListener {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
MusicPlayerRemote.pauseSong()
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying()
|
||||
}
|
||||
}
|
||||
binding.title.isSelected = true
|
||||
binding.text.isSelected = true
|
||||
binding.title.setOnClickListener {
|
||||
goToAlbum(requireActivity())
|
||||
}
|
||||
binding.text.setOnClickListener {
|
||||
goToArtist(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun setColor(color: MediaNotificationProcessor) {
|
||||
val colorBg = ATHUtil.resolveColor(requireContext(), android.R.attr.colorBackground)
|
||||
if (ColorUtil.isColorLight(colorBg)) {
|
||||
lastPlaybackControlsColor =
|
||||
MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
|
||||
lastDisabledPlaybackControlsColor =
|
||||
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
|
||||
} else {
|
||||
lastPlaybackControlsColor =
|
||||
MaterialValueHelper.getPrimaryTextColor(requireContext(), false)
|
||||
lastDisabledPlaybackControlsColor =
|
||||
MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
|
||||
}
|
||||
|
||||
val colorFinal = if (PreferenceUtil.isAdaptiveColor) {
|
||||
color.primaryTextColor
|
||||
} else {
|
||||
ThemeStore.accentColor(requireContext())
|
||||
}.ripAlpha()
|
||||
|
||||
TintHelper.setTintAuto(
|
||||
binding.playPauseButton,
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
requireContext(),
|
||||
ColorUtil.isColorLight(colorFinal)
|
||||
),
|
||||
false
|
||||
)
|
||||
binding.playPauseCard.setCardBackgroundColor(colorFinal)
|
||||
|
||||
binding.progressSlider.applyColor(colorFinal)
|
||||
volumeFragment?.setTintable(colorFinal)
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updatePrevNextColor()
|
||||
updatePlayPauseDrawableState()
|
||||
}
|
||||
|
||||
private fun updateSong() {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
binding.title.text = song.title
|
||||
binding.text.text = song.artistName
|
||||
|
||||
if (PreferenceUtil.isSongInfo) {
|
||||
binding.songInfo.text = getSongInfo(song)
|
||||
binding.songInfo.show()
|
||||
} else {
|
||||
binding.songInfo.hide()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
progressViewUpdateHelper.start()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
progressViewUpdateHelper.stop()
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
updatePlayPauseDrawableState()
|
||||
updateRepeatState()
|
||||
updateShuffleState()
|
||||
updateSong()
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
updateSong()
|
||||
}
|
||||
|
||||
override fun onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState()
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged() {
|
||||
updateRepeatState()
|
||||
}
|
||||
|
||||
override fun onShuffleModeChanged() {
|
||||
updateShuffleState()
|
||||
}
|
||||
|
||||
private fun setUpPlayPauseFab() {
|
||||
binding.playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
|
||||
updatePlayPauseDrawableState()
|
||||
}
|
||||
|
||||
private fun updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying) {
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_pause_outline_small)
|
||||
binding.playPauseCard.animateRadius(40F)
|
||||
} else {
|
||||
binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_outline_small)
|
||||
binding.playPauseCard.animateToCircle()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpMusicControllers() {
|
||||
setUpPlayPauseFab()
|
||||
}
|
||||
|
||||
public override fun show() {
|
||||
binding.playPauseButton.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(DecelerateInterpolator())
|
||||
.start()
|
||||
}
|
||||
|
||||
public override fun hide() {
|
||||
binding.playPauseButton.apply {
|
||||
scaleX = 0f
|
||||
scaleY = 0f
|
||||
rotation = 0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUpdateProgressViews(progress: Int, total: Int) {
|
||||
binding.progressSlider.max = total
|
||||
|
||||
val animator = ObjectAnimator.ofInt(binding.progressSlider, "progress", progress)
|
||||
animator.duration = SLIDER_ANIMATION_TIME
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.start()
|
||||
|
||||
binding.songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
|
||||
binding.songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarla.
|
||||
*
|
||||
* 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.fragments.player.md3
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentMd3PlayerBinding
|
||||
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
|
||||
class MD3PlayerFragment : AbsPlayerFragment(R.layout.fragment_md3_player) {
|
||||
|
||||
private var lastColor: Int = 0
|
||||
override val paletteColor: Int
|
||||
get() = lastColor
|
||||
|
||||
private lateinit var controlsFragment: MD3PlaybackControlsFragment
|
||||
|
||||
private var _binding: FragmentMd3PlayerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onShow() {
|
||||
controlsFragment.show()
|
||||
}
|
||||
|
||||
override fun onHide() {
|
||||
controlsFragment.hide()
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toolbarIconColor(): Int {
|
||||
return ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal)
|
||||
}
|
||||
|
||||
override fun onColorChanged(color: MediaNotificationProcessor) {
|
||||
controlsFragment.setColor(color)
|
||||
lastColor = color.backgroundColor
|
||||
libraryViewModel.updateColor(color.backgroundColor)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
|
||||
override fun toggleFavorite(song: Song) {
|
||||
super.toggleFavorite(song)
|
||||
if (song.id == MusicPlayerRemote.currentSong.id) {
|
||||
updateIsFavorite()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentMd3PlayerBinding.bind(view)
|
||||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
playerToolbar().drawAboveSystemBars()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
controlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as MD3PlaybackControlsFragment
|
||||
val playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playerAlbumCoverFragment.setCallbacks(this)
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
binding.playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
//binding.playerToolbar.menu.setUpWithIcons()
|
||||
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
binding.playerToolbar,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
updateIsFavorite()
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
updateIsFavorite()
|
||||
}
|
||||
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return binding.playerToolbar
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): MD3PlayerFragment {
|
||||
return MD3PlayerFragment()
|
||||
}
|
||||
}
|
||||
}
|
16
app/src/main/res/drawable/ic_pause_outline_small.xml
Normal file
16
app/src/main/res/drawable/ic_pause_outline_small.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:strokeWidth="1.5"
|
||||
android:pathData="M6.5,5.5h3v13h-3z"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000" />
|
||||
<path
|
||||
android:strokeWidth="1.5"
|
||||
android:pathData="M14.5,5.5h3v13h-3z"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_play_arrow_outline_small.xml
Normal file
10
app/src/main/res/drawable/ic_play_arrow_outline_small.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10,8.64L15.27,12 10,15.36V8.64M8,5v14l11,-7L8,5z" />
|
||||
</vector>
|
83
app/src/main/res/layout-land/fragment_md3_player.xml
Normal file
83
app/src/main/res/layout-land/fragment_md3_player.xml
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface" />
|
||||
|
||||
<View
|
||||
android:id="@+id/colorGradientBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
||||
<include layout="@layout/shadow_statusbar_toolbar" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<include layout="@layout/status_bar" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<code.name.monkey.retromusic.views.HeightFitSquareLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/playerAlbumCoverFragment"
|
||||
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:layout="@layout/fragment_album_cover" />
|
||||
</code.name.monkey.retromusic.views.HeightFitSquareLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/controlsContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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:navigationIcon="@drawable/ic_keyboard_arrow_down_black"
|
||||
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black" />
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/playbackControlsFragment"
|
||||
android:name="code.name.monkey.retromusic.fragments.player.md3.MD3PlaybackControlsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_weight="1"
|
||||
tools:layout="@layout/fragment_md3_player_playback_controls" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
58
app/src/main/res/layout/fragment_md3_player.xml
Normal file
58
app/src/main/res/layout/fragment_md3_player.xml
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
<include layout="@layout/shadow_statusbar_toolbar" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/statusBarContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<include layout="@layout/status_bar" />
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/playerAlbumCoverFragment"
|
||||
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHeight_percent="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/statusBarContainer" />
|
||||
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/playbackControlsFragment"
|
||||
android:name="code.name.monkey.retromusic.fragments.player.md3.MD3PlaybackControlsFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/playerToolbar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/playerAlbumCoverFragment"
|
||||
tools:layout="@layout/fragment_md3_player_playback_controls" />
|
||||
|
||||
|
||||
<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"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/playbackControlsFragment"
|
||||
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,210 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/songCurrentProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:gravity="center"
|
||||
android:minWidth="40dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/progressSlider"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
tools:text="@tools:sample/date/hhmmss" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSeekBar
|
||||
android:id="@+id/progressSlider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:maxHeight="2dp"
|
||||
android:paddingVertical="@dimen/seekbar_padding"
|
||||
android:progressDrawable="@drawable/color_progress_seek"
|
||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="RtlHardcoded,UnusedAttribute"
|
||||
tools:progress="20" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/songTotalTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:gravity="center"
|
||||
android:minWidth="40dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/progressSlider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/progressSlider"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||
tools:text="@tools:sample/date/hhmmss" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:ellipsize="marquee"
|
||||
android:focusable="true"
|
||||
android:freezesText="true"
|
||||
android:gravity="center"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/playPauseCard"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/progressSlider"
|
||||
app:layout_constraintVertical_bias="0.3"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="marquee"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:freezesText="true"
|
||||
android:gravity="center"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextViewBody1"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/songInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/previousButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/playPauseCard"
|
||||
app:layout_constraintEnd_toStartOf="@id/playPauseCard"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/playPauseCard"
|
||||
app:srcCompat="@drawable/ic_skip_previous_outline"
|
||||
tools:backgroundTint="?colorPrimaryDark"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:tint="@color/md_black_1000" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/playPauseCard"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardBackgroundColor="?colorSecondary"
|
||||
app:cardCornerRadius="40dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/repeatButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text"
|
||||
tools:tint="@color/md_black_1000">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/playPauseButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/transparent"
|
||||
android:padding="32dp"
|
||||
app:srcCompat="@drawable/ic_pause_outline_small"
|
||||
tools:tint="@color/md_black_1000" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:padding="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/playPauseCard"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/playPauseCard"
|
||||
app:layout_constraintTop_toTopOf="@+id/playPauseCard"
|
||||
app:srcCompat="@drawable/ic_skip_next_outline"
|
||||
tools:backgroundTint="?colorPrimaryDark"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:tint="@color/md_black_1000" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/shuffleButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:background="@null"
|
||||
android:paddingVertical="16dp"
|
||||
android:src="@drawable/ic_shuffle"
|
||||
app:layout_constraintBottom_toTopOf="@+id/songInfo"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/repeatButton"
|
||||
app:layout_constraintTop_toBottomOf="@+id/playPauseCard"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:tint="@color/md_black_1000" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/repeatButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:background="@null"
|
||||
android:paddingVertical="16dp"
|
||||
android:src="@drawable/ic_repeat"
|
||||
app:layout_constraintBottom_toTopOf="@+id/songInfo"
|
||||
app:layout_constraintEnd_toStartOf="@id/shuffleButton"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/playPauseCard"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:tint="@color/md_black_1000" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/volumeFragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:background="@color/md_red_400"
|
||||
tools:layout_height="52dp" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -239,6 +239,7 @@
|
|||
<string name="material">Material</string>
|
||||
<string name="md_error_label">Error</string>
|
||||
<string name="md_storage_perm_error">Permission error</string>
|
||||
<string name="md3" translatable="false">MD3</string>
|
||||
<string name="my_name">Name</string>
|
||||
<string name="my_top_tracks">Most played</string>
|
||||
<string name="never">Never</string>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue