diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 78fd9f8cc..bcf1e6321 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -13,8 +13,6 @@ import androidx.navigation.NavController import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment 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.detail.DetailViewModel import org.oxycblt.auxio.music.MusicStore @@ -72,8 +70,6 @@ class MainFragment : Fragment() { binding.navBar.itemIconTintList = 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 -> binding.navBar.setOnNavigationItemSelectedListener { navigateWithItem(controller, it) @@ -91,7 +87,7 @@ class MainFragment : Fragment() { ) binding.compactPlayback.visibility = View.GONE - playbackModel.resetCanAnimate() + playbackModel.disableAnimation() } else { binding.compactPlayback.visibility = View.VISIBLE } @@ -100,11 +96,12 @@ class MainFragment : Fragment() { playbackModel.navToSong.observe(viewLifecycleOwner) { if (it) { if (binding.navBar.selectedItemId != R.id.library_fragment || - (navController!!.currentDestination?.id == R.id.album_detail_fragment - && detailModel.currentAlbum.value == null - || detailModel.currentAlbum.value?.id - != playbackModel.song.value!!.album.id - ) || + ( + navController!!.currentDestination?.id == R.id.album_detail_fragment && + detailModel.currentAlbum.value == null || + detailModel.currentAlbum.value?.id + != playbackModel.song.value!!.album.id + ) || navController.currentDestination?.id == R.id.artist_detail_fragment || navController.currentDestination?.id == R.id.genre_detail_fragment ) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt index c537da8bb..fed2de892 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ImageView import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -14,6 +15,7 @@ import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding 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. @@ -25,6 +27,8 @@ import org.oxycblt.auxio.music.MusicStore class CompactPlaybackFragment : Fragment() { private val playbackModel: PlaybackViewModel by activityViewModels() + private var playbackControls: ImageView? = null + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -32,14 +36,6 @@ class CompactPlaybackFragment : Fragment() { ): View { 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 --- binding.lifecycleOwner = viewLifecycleOwner @@ -57,9 +53,12 @@ class CompactPlaybackFragment : Fragment() { binding.root.setOnLongClickListener { playbackModel.navToPlayingSong() - /* + true + } + + binding.playbackControls.setOnLongClickListener { playbackModel.save(requireContext()) - getString(R.string.debug_state_saved).createToast(requireContext()) */ + getString(R.string.debug_state_saved).createToast(requireContext()) 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) { binding.playbackProgress.progress = it } + // Use the playback control ImageView for later. + playbackControls = binding.playbackControls + Log.d(this::class.simpleName, "Fragment Created") 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() { super.onDestroy() - playbackModel.resetCanAnimate() + playbackControls = null } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt index 3049d1e77..20dc643e9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt @@ -436,8 +436,9 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca NotificationUtils.ACTION_LOOP -> playbackManager.setLoopMode(playbackManager.loopMode.increment()) NotificationUtils.ACTION_SKIP_PREV -> playbackManager.prev() - NotificationUtils.ACTION_PLAY_PAUSE -> + NotificationUtils.ACTION_PLAY_PAUSE -> { playbackManager.setPlayingStatus(!playbackManager.isPlaying) + } NotificationUtils.ACTION_SKIP_NEXT -> playbackManager.next() NotificationUtils.ACTION_EXIT -> stop() diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index bfcc4bdca..a5d394692 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -248,7 +248,7 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { // Flip the playing status. fun invertPlayingStatus() { - mCanAnimate = true + enableAnimation() playbackManager.setPlayingStatus(!playbackManager.isPlaying) } @@ -290,7 +290,11 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { mNavToSong.value = false } - fun resetCanAnimate() { + fun enableAnimation() { + mCanAnimate = true + } + + fun disableAnimation() { mCanAnimate = false } @@ -332,8 +336,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { override fun onPlayingUpdate(isPlaying: Boolean) { mIsPlaying.value = isPlaying - - mCanAnimate = true } override fun onShuffleUpdate(isShuffling: Boolean) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index b061b929f..de877c4e9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -545,7 +545,6 @@ class PlaybackStateManager private constructor() { mShuffleSeed = playbackState.shuffleSeed mIsInUserQueue = playbackState.inUserQueue mIndex = playbackState.index - mIsPlaying = false callbacks.forEach { it.onSeekConfirm(mPosition)