Improved carousel effect

This commit is contained in:
h4h13 2019-07-31 00:00:19 +05:30
parent 310cfe8491
commit 0b025f3516
10 changed files with 234 additions and 73 deletions

View file

@ -94,6 +94,8 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
var finalLayout = layout var finalLayout = layout
if (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.CLASSIC) { if (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.CLASSIC) {
finalLayout = R.layout.fragment_album_full_cover finalLayout = R.layout.fragment_album_full_cover
} else if (PreferenceUtil.getInstance().carouselEffect()) {
finalLayout= R.layout.fragment_album_carousel_cover;
} }
val view = inflater.inflate(finalLayout, container, false) val view = inflater.inflate(finalLayout, container, false)
albumCover = view.findViewById(R.id.player_image) albumCover = view.findViewById(R.id.player_image)

View file

@ -16,54 +16,36 @@ package code.name.monkey.retromusic.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.loaders.PlaylistLoader import code.name.monkey.retromusic.loaders.PlaylistLoader
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.adapter.playlist.AddToPlaylist import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.android.synthetic.main.dialog_add_to_playlist.*
class AddToPlaylistDialog : DialogFragment() { class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog(
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { savedInstanceState: Bundle?
): Dialog {
return super.onCreateDialog(savedInstanceState) val cntx = requireContext()
val playlists = PlaylistLoader.getAllPlaylists(cntx).blockingFirst()
val playlistNames = arrayOfNulls<CharSequence>(playlists.size + 1)
playlistNames[0] = cntx.resources.getString(code.name.monkey.retromusic.R.string.action_new_playlist)
return MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.add_playlist_title)
.setItems(playlistNames) { dialog, which ->
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@setItems
if (which == 0) {
dialog.dismiss()
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") }
} else {
dialog.dismiss()
PlaylistsUtil.addToPlaylist(cntx, songs, playlists[which - 1].id, true)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_add_to_playlist, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val songs = arguments!!.getParcelableArrayList<Song>("songs")
actionAddPlaylist.setOnClickListener {
CreatePlaylistDialog.create(songs!!).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
dismiss()
}
bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
val playlists = PlaylistLoader.getAllPlaylists(activity!!).blockingFirst()
val playlistAdapter = AddToPlaylist(activity!!, playlists, R.layout.item_playlist, songs!!, dialog!!)
recyclerView.apply {
layoutManager = LinearLayoutManager(context)
itemAnimator = DefaultItemAnimator()
adapter = playlistAdapter
} }
.create()
} }
companion object { companion object {

View file

@ -35,7 +35,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onClick(view: View) { override fun onClick(view: View) {
when (view.id) { when (view.id) {
R.id.actionPlayingQueue -> NavigationUtil.goToPlayingQueue(activity!!) R.id.actionPlayingQueue -> NavigationUtil.goToPlayingQueue(requireActivity())
R.id.actionNext -> MusicPlayerRemote.playNextSong() R.id.actionNext -> MusicPlayerRemote.playNextSong()
R.id.actionPrevious -> MusicPlayerRemote.back() R.id.actionPrevious -> MusicPlayerRemote.back()
} }
@ -44,8 +44,8 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(ThemeStore.primaryColor(context!!)) view.setBackgroundColor(ThemeStore.primaryColor(requireContext()))
view.setOnTouchListener(FlingPlayBackController(context!!)) view.setOnTouchListener(FlingPlayBackController(requireContext()))
//view.setOnClickListener(v -> NavigationUtil.gotoNowPlayingActivity(getContext())); //view.setOnClickListener(v -> NavigationUtil.gotoNowPlayingActivity(getContext()));
setUpMiniPlayer() setUpMiniPlayer()
@ -66,7 +66,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
private fun setUpMiniPlayer() { private fun setUpMiniPlayer() {
setUpPlayPauseButton() setUpPlayPauseButton()
ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(context!!)) ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(requireContext()))
} }
private fun setUpPlayPauseButton() { private fun setUpPlayPauseButton() {
@ -78,10 +78,10 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
val title = SpannableString(song.title) val title = SpannableString(song.title)
title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(context!!)), 0, title.length, 0) title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(requireContext())), 0, title.length, 0)
val text = SpannableString(song.artistName) val text = SpannableString(song.artistName)
text.setSpan(ForegroundColorSpan(ThemeStore.textColorSecondary(context!!)), 0, text.length, 0) text.setSpan(ForegroundColorSpan(ThemeStore.textColorSecondary(requireContext())), 0, text.length, 0)
builder.append(title).append("").append(text) builder.append(title).append("").append(text)

View file

@ -111,6 +111,8 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
fun setTintable(color: Int) { fun setTintable(color: Int) {
ViewUtil.setProgressDrawable(volumeSeekBar, color, true) ViewUtil.setProgressDrawable(volumeSeekBar, color, true)
volumeDown.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
volumeUp.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
} }
fun removeThumb() { fun removeThumb() {

View file

@ -5,12 +5,14 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter.AlbumCoverFragment
import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.transform.CarousalPagerTransformer import code.name.monkey.retromusic.transform.CarousalPagerTransformer
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter
import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_album_cover.* import kotlinx.android.synthetic.main.fragment_player_album_cover.*
@ -18,11 +20,9 @@ import kotlinx.android.synthetic.main.fragment_player_album_cover.*
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 : AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver { private val colorReceiver = object : AlbumCoverFragment.ColorReceiver {
override fun onColorReady(color: Int, request: Int) { override fun onColorReady(color: Int, request: Int) {
if (currentPosition == request) { if (currentPosition == request) {
notifyColorChange(color) notifyColorChange(color)
@ -31,7 +31,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
} }
fun removeSlideEffect() { fun removeSlideEffect() {
val transformer = ParallaxPagerTransformer(code.name.monkey.retromusic.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)
@ -39,7 +39,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
return inflater.inflate(code.name.monkey.retromusic.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?) {
@ -53,9 +53,9 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
(PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.ADAPTIVE) (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
|| (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.FIT))) { || (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.FIT))) {
viewPager.clipToPadding = false viewPager.clipToPadding = false
viewPager.setPadding(96, 0, 96, 0) viewPager.setPadding(40, 40, 40, 0)
viewPager.pageMargin = 18 viewPager.pageMargin = 16
viewPager.setPageTransformer(false, CarousalPagerTransformer(context!!)) viewPager.setPageTransformer(false, CarousalPagerTransformer(requireContext()))
} else { } else {
viewPager.offscreenPageLimit = 2 viewPager.offscreenPageLimit = 2
viewPager.setPageTransformer(true, PreferenceUtil.getInstance().albumCoverTransform) viewPager.setPageTransformer(true, PreferenceUtil.getInstance().albumCoverTransform)
@ -66,7 +66,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
viewPager.removeOnPageChangeListener(this) viewPager.removeOnPageChangeListener(this)
} }
@ -134,7 +133,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
} }
companion object { companion object {
val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName

View file

@ -12,19 +12,21 @@ import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator import android.view.animation.LinearInterpolator
import android.widget.SeekBar import android.widget.SeekBar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_playback_controls.* import kotlinx.android.synthetic.main.fragment_blur_player_playback_controls.*
import kotlinx.android.synthetic.main.media_button.* import kotlinx.android.synthetic.main.media_button.*
@ -42,7 +44,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_player_playback_controls, container, false) return inflater.inflate(R.layout.fragment_blur_player_playback_controls, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -57,13 +59,13 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
showBonceAnimation() showBonceAnimation()
} }
text.isSelected = true
} }
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
title.text = song.title title.text = song.title
text.text = song.artistName text.text = "${song.artistName}${song.albumName}"
} }
override fun onResume() { override fun onResume() {
@ -102,20 +104,28 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun setDark(color: Int) { override fun setDark(color: Int) {
lastPlaybackControlsColor = Color.WHITE lastPlaybackControlsColor = Color.WHITE
lastDisabledPlaybackControlsColor = ContextCompat.getColor(context!!, R.color.md_grey_500) lastDisabledPlaybackControlsColor = ContextCompat.getColor(requireContext(), R.color.md_grey_500)
title.setTextColor(lastPlaybackControlsColor) title.setTextColor(lastPlaybackControlsColor)
text.setTextColor(lastDisabledPlaybackControlsColor)
setFabColor(lastPlaybackControlsColor)
ViewUtil.setProgressDrawable(progressSlider, lastPlaybackControlsColor)
songCurrentProgress.setTextColor(lastPlaybackControlsColor) songCurrentProgress.setTextColor(lastPlaybackControlsColor)
songTotalTime.setTextColor(lastPlaybackControlsColor) songTotalTime.setTextColor(lastPlaybackControlsColor)
updateRepeatState() updateRepeatState()
updateShuffleState() updateShuffleState()
updatePrevNextColor() updatePrevNextColor()
volumeFragment?.tintWhiteColor()
val colorFinal = if (PreferenceUtil.getInstance().adaptiveColor) {
color
} else {
ThemeStore.accentColor(requireContext())
}.ripAlpha()
text.setTextColor(colorFinal)
TintHelper.setTintAuto(progressSlider, colorFinal, false)
volumeFragment?.setTintable(colorFinal)
setFabColor(colorFinal)
} }
private fun setFabColor(i: Int) { private fun setFabColor(i: Int) {

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.transform
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import kotlin.math.abs
class CarousalPagerTransformer(context: Context) : ViewPager.PageTransformer { class CarousalPagerTransformer(context: Context) : ViewPager.PageTransformer {
@ -35,8 +36,8 @@ class CarousalPagerTransformer(context: Context) : ViewPager.PageTransformer {
val leftInScreen = view.left - viewPager!!.scrollX val leftInScreen = view.left - viewPager!!.scrollX
val centerXInViewPager = leftInScreen + view.measuredWidth / 2 val centerXInViewPager = leftInScreen + view.measuredWidth / 2
val offsetX = centerXInViewPager - viewPager!!.measuredWidth / 2 val offsetX = centerXInViewPager - viewPager!!.measuredWidth / 2
val offsetRate = offsetX.toFloat() * 0.20f / viewPager!!.measuredWidth val offsetRate = offsetX.toFloat() * 0.30f / viewPager!!.measuredWidth
val scaleFactor = 1 - Math.abs(offsetRate) val scaleFactor = 1 - abs(offsetRate)
if (scaleFactor > 0) { if (scaleFactor > 0) {
view.scaleX = scaleFactor view.scaleX = scaleFactor
view.scaleY = scaleFactor view.scaleY = scaleFactor

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 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.
-->
<code.name.monkey.retromusic.views.WidthFitSquareLayout 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="wrap_content"
android:layout_gravity="center">
<com.google.android.material.card.MaterialCardView
android:id="@+id/player_album_art_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
app:cardCornerRadius="8dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/player_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription,UnusedAttribute" />
</com.google.android.material.card.MaterialCardView>
</code.name.monkey.retromusic.views.WidthFitSquareLayout>

View file

@ -16,7 +16,7 @@
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/shadow_up_strong" /> android:background="@drawable/shadow_up_full_theme" />
<View <View
android:id="@+id/mask" android:id="@+id/mask"

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
tools:ignore="MissingPrefix">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="@color/md_white_1000"
android:textSize="22sp"
tools:text="Title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="28dp"
android:paddingStart="12dp"
android:layout_marginTop="12dp"
android:paddingEnd="12dp">
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="1.5dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry" />
</RelativeLayout>
<include layout="@layout/media_button" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingStart="8dp"
android:paddingEnd="8dp" />
</LinearLayout>