Fix bugs with play-pause animation
Fix some bugs that will cause the animation on the play/pause button not to show.
This commit is contained in:
parent
cc9a952b9a
commit
034f073bac
5 changed files with 66 additions and 46 deletions
|
@ -13,8 +13,6 @@ import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.ui.NavigationUI
|
|
||||||
import androidx.navigation.ui.setupWithNavController
|
|
||||||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
|
@ -72,8 +70,6 @@ class MainFragment : Fragment() {
|
||||||
binding.navBar.itemIconTintList = navTints
|
binding.navBar.itemIconTintList = navTints
|
||||||
binding.navBar.itemTextColor = navTints
|
binding.navBar.itemTextColor = navTints
|
||||||
|
|
||||||
// TODO: Add the navigation
|
|
||||||
// Do the trick to test if the memleak is real: Nav to songs, nav to playing, nav out of playing, nav to playing album, nav to songs
|
|
||||||
navController?.let { controller ->
|
navController?.let { controller ->
|
||||||
binding.navBar.setOnNavigationItemSelectedListener {
|
binding.navBar.setOnNavigationItemSelectedListener {
|
||||||
navigateWithItem(controller, it)
|
navigateWithItem(controller, it)
|
||||||
|
@ -91,7 +87,7 @@ class MainFragment : Fragment() {
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.compactPlayback.visibility = View.GONE
|
binding.compactPlayback.visibility = View.GONE
|
||||||
playbackModel.resetCanAnimate()
|
playbackModel.disableAnimation()
|
||||||
} else {
|
} else {
|
||||||
binding.compactPlayback.visibility = View.VISIBLE
|
binding.compactPlayback.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
@ -100,9 +96,10 @@ class MainFragment : Fragment() {
|
||||||
playbackModel.navToSong.observe(viewLifecycleOwner) {
|
playbackModel.navToSong.observe(viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
if (binding.navBar.selectedItemId != R.id.library_fragment ||
|
if (binding.navBar.selectedItemId != R.id.library_fragment ||
|
||||||
(navController!!.currentDestination?.id == R.id.album_detail_fragment
|
(
|
||||||
&& detailModel.currentAlbum.value == null
|
navController!!.currentDestination?.id == R.id.album_detail_fragment &&
|
||||||
|| detailModel.currentAlbum.value?.id
|
detailModel.currentAlbum.value == null ||
|
||||||
|
detailModel.currentAlbum.value?.id
|
||||||
!= playbackModel.song.value!!.album.id
|
!= playbackModel.song.value!!.album.id
|
||||||
) ||
|
) ||
|
||||||
navController.currentDestination?.id == R.id.artist_detail_fragment ||
|
navController.currentDestination?.id == R.id.artist_detail_fragment ||
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
@ -14,6 +15,7 @@ import org.oxycblt.auxio.MainFragmentDirections
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding
|
import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
|
import org.oxycblt.auxio.ui.createToast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [Fragment] that displays the currently played song at a glance, with some basic controls.
|
* A [Fragment] that displays the currently played song at a glance, with some basic controls.
|
||||||
|
@ -25,6 +27,8 @@ import org.oxycblt.auxio.music.MusicStore
|
||||||
class CompactPlaybackFragment : Fragment() {
|
class CompactPlaybackFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
|
|
||||||
|
private var playbackControls: ImageView? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -32,14 +36,6 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
): View {
|
): View {
|
||||||
val binding = FragmentCompactPlaybackBinding.inflate(inflater)
|
val binding = FragmentCompactPlaybackBinding.inflate(inflater)
|
||||||
|
|
||||||
val iconPauseToPlay = ContextCompat.getDrawable(
|
|
||||||
requireContext(), R.drawable.ic_pause_to_play
|
|
||||||
) as AnimatedVectorDrawable
|
|
||||||
|
|
||||||
val iconPlayToPause = ContextCompat.getDrawable(
|
|
||||||
requireContext(), R.drawable.ic_play_to_pause
|
|
||||||
) as AnimatedVectorDrawable
|
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.lifecycleOwner = viewLifecycleOwner
|
binding.lifecycleOwner = viewLifecycleOwner
|
||||||
|
@ -57,9 +53,12 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
|
|
||||||
binding.root.setOnLongClickListener {
|
binding.root.setOnLongClickListener {
|
||||||
playbackModel.navToPlayingSong()
|
playbackModel.navToPlayingSong()
|
||||||
/*
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.playbackControls.setOnLongClickListener {
|
||||||
playbackModel.save(requireContext())
|
playbackModel.save(requireContext())
|
||||||
getString(R.string.debug_state_saved).createToast(requireContext()) */
|
getString(R.string.debug_state_saved).createToast(requireContext())
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,37 +73,59 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
|
||||||
if (playbackModel.canAnimate) {
|
|
||||||
if (it) {
|
|
||||||
// Animate the icon transition when the playing status switches
|
|
||||||
binding.playbackControls.setImageDrawable(iconPlayToPause)
|
|
||||||
iconPlayToPause.start()
|
|
||||||
} else {
|
|
||||||
binding.playbackControls.setImageDrawable(iconPauseToPlay)
|
|
||||||
iconPauseToPlay.start()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it) {
|
|
||||||
binding.playbackControls.setImageResource(R.drawable.ic_pause_large)
|
|
||||||
} else {
|
|
||||||
binding.playbackControls.setImageResource(R.drawable.ic_play_large)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
|
playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
|
||||||
binding.playbackProgress.progress = it
|
binding.playbackProgress.progress = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the playback control ImageView for later.
|
||||||
|
playbackControls = binding.playbackControls
|
||||||
|
|
||||||
Log.d(this::class.simpleName, "Fragment Created")
|
Log.d(this::class.simpleName, "Fragment Created")
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
playbackModel.disableAnimation()
|
||||||
|
|
||||||
|
// Observe the changes to isPlaying for
|
||||||
|
val iconPauseToPlay = ContextCompat.getDrawable(
|
||||||
|
requireContext(), R.drawable.ic_pause_to_play
|
||||||
|
) as AnimatedVectorDrawable
|
||||||
|
|
||||||
|
val iconPlayToPause = ContextCompat.getDrawable(
|
||||||
|
requireContext(), R.drawable.ic_play_to_pause
|
||||||
|
) as AnimatedVectorDrawable
|
||||||
|
|
||||||
|
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
||||||
|
if (playbackModel.canAnimate) {
|
||||||
|
if (it) {
|
||||||
|
// Animate the icon transition when the playing status switches
|
||||||
|
playbackControls?.setImageDrawable(iconPlayToPause)
|
||||||
|
iconPlayToPause.start()
|
||||||
|
} else {
|
||||||
|
playbackControls?.setImageDrawable(iconPauseToPlay)
|
||||||
|
iconPauseToPlay.start()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use static icons on the first firing of this observer so that the icons
|
||||||
|
// don't animate on startup, which looks weird.
|
||||||
|
if (it) {
|
||||||
|
playbackControls?.setImageResource(R.drawable.ic_pause_large)
|
||||||
|
} else {
|
||||||
|
playbackControls?.setImageResource(R.drawable.ic_play_large)
|
||||||
|
}
|
||||||
|
|
||||||
|
playbackModel.enableAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|
||||||
playbackModel.resetCanAnimate()
|
playbackControls = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,8 +436,9 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
|
||||||
NotificationUtils.ACTION_LOOP ->
|
NotificationUtils.ACTION_LOOP ->
|
||||||
playbackManager.setLoopMode(playbackManager.loopMode.increment())
|
playbackManager.setLoopMode(playbackManager.loopMode.increment())
|
||||||
NotificationUtils.ACTION_SKIP_PREV -> playbackManager.prev()
|
NotificationUtils.ACTION_SKIP_PREV -> playbackManager.prev()
|
||||||
NotificationUtils.ACTION_PLAY_PAUSE ->
|
NotificationUtils.ACTION_PLAY_PAUSE -> {
|
||||||
playbackManager.setPlayingStatus(!playbackManager.isPlaying)
|
playbackManager.setPlayingStatus(!playbackManager.isPlaying)
|
||||||
|
}
|
||||||
NotificationUtils.ACTION_SKIP_NEXT -> playbackManager.next()
|
NotificationUtils.ACTION_SKIP_NEXT -> playbackManager.next()
|
||||||
NotificationUtils.ACTION_EXIT -> stop()
|
NotificationUtils.ACTION_EXIT -> stop()
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
|
|
||||||
// Flip the playing status.
|
// Flip the playing status.
|
||||||
fun invertPlayingStatus() {
|
fun invertPlayingStatus() {
|
||||||
mCanAnimate = true
|
enableAnimation()
|
||||||
|
|
||||||
playbackManager.setPlayingStatus(!playbackManager.isPlaying)
|
playbackManager.setPlayingStatus(!playbackManager.isPlaying)
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,11 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
mNavToSong.value = false
|
mNavToSong.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetCanAnimate() {
|
fun enableAnimation() {
|
||||||
|
mCanAnimate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disableAnimation() {
|
||||||
mCanAnimate = false
|
mCanAnimate = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,8 +336,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
|
|
||||||
override fun onPlayingUpdate(isPlaying: Boolean) {
|
override fun onPlayingUpdate(isPlaying: Boolean) {
|
||||||
mIsPlaying.value = isPlaying
|
mIsPlaying.value = isPlaying
|
||||||
|
|
||||||
mCanAnimate = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShuffleUpdate(isShuffling: Boolean) {
|
override fun onShuffleUpdate(isShuffling: Boolean) {
|
||||||
|
|
|
@ -545,7 +545,6 @@ class PlaybackStateManager private constructor() {
|
||||||
mShuffleSeed = playbackState.shuffleSeed
|
mShuffleSeed = playbackState.shuffleSeed
|
||||||
mIsInUserQueue = playbackState.inUserQueue
|
mIsInUserQueue = playbackState.inUserQueue
|
||||||
mIndex = playbackState.index
|
mIndex = playbackState.index
|
||||||
mIsPlaying = false
|
|
||||||
|
|
||||||
callbacks.forEach {
|
callbacks.forEach {
|
||||||
it.onSeekConfirm(mPosition)
|
it.onSeekConfirm(mPosition)
|
||||||
|
|
Loading…
Reference in a new issue