Refactor playing indicator holder usage

Collapse the two lastHolder values into one value inside the detail adapters in order to cut down on needless redundancy.
This commit is contained in:
OxygenCobalt 2020-12-31 08:05:34 -07:00
parent 38197344f6
commit 33abb1419a
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 46 additions and 72 deletions

View file

@ -16,7 +16,6 @@ import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.recycler.CenterSmoothScroller
import org.oxycblt.auxio.recycler.Highlightable
import org.oxycblt.auxio.ui.createToast
import org.oxycblt.auxio.ui.setupAlbumSongActions
@ -136,42 +135,16 @@ class AlbumDetailFragment : DetailFragment() {
if (playbackModel.mode.value == PlaybackMode.IN_ALBUM &&
playbackModel.parent.value?.id == detailModel.currentAlbum.value!!.id
) {
detailAdapter.setCurrentSong(song)
lastHolder?.setHighlighted(false)
lastHolder = null
if (song != null) {
// Use existing data instead of having to re-sort it.
val pos = detailAdapter.currentList.indexOfFirst {
it.name == song.name
}
// Check if the ViewHolder for this song is visible, if it is then highlight it.
// If the ViewHolder is not visible, then the adapter should take care of it if it does become visible.
binding.detailRecycler.layoutManager?.findViewByPosition(pos)?.let { child ->
binding.detailRecycler.getChildViewHolder(child)?.let {
lastHolder = it as Highlightable
lastHolder?.setHighlighted(true)
}
}
}
detailAdapter.highlightSong(song, binding.detailRecycler)
} else {
// Clear the viewholders if the mode isn't ALL_SONGS
detailAdapter.setCurrentSong(null)
lastHolder?.setHighlighted(false)
lastHolder = null
detailAdapter.highlightSong(null, binding.detailRecycler)
}
}
playbackModel.isInUserQueue.observe(viewLifecycleOwner) {
if (it) {
// Remove any highlighted ViewHolders if the playback is in the user queue.
detailAdapter.setCurrentSong(null)
lastHolder?.setHighlighted(false)
lastHolder = null
detailAdapter.highlightSong(null, binding.detailRecycler)
}
}

View file

@ -15,7 +15,6 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.recycler.Highlightable
import org.oxycblt.auxio.ui.setupAlbumActions
/**
@ -111,32 +110,9 @@ class ArtistDetailFragment : DetailFragment() {
playbackModel.parent.observe(viewLifecycleOwner) { parent ->
if (playbackModel.mode.value == PlaybackMode.IN_ALBUM && parent is Album?) {
detailAdapter.setCurrentAlbum(parent)
lastHolder?.setHighlighted(false)
lastHolder = null
if (parent != null) {
// Use existing data instead of having to re-sort it.
val pos = detailAdapter.currentList.indexOfFirst {
it.name == parent.name
}
// Check if the ViewHolder if this album is visible, and highlight it if so.
binding.detailRecycler.layoutManager?.findViewByPosition(pos)?.let { child ->
binding.detailRecycler.getChildViewHolder(child)?.let {
lastHolder = it as Highlightable
lastHolder?.setHighlighted(true)
}
}
}
detailAdapter.setCurrentAlbum(parent, binding.detailRecycler)
} else {
// Clear the viewholders if the mode isn't IN_ALBUM
detailAdapter.setCurrentAlbum(null)
lastHolder?.setHighlighted(false)
lastHolder = null
detailAdapter.setCurrentAlbum(null, binding.detailRecycler)
}
}

View file

@ -29,7 +29,6 @@ abstract class DetailFragment : Fragment() {
protected val binding: FragmentDetailBinding by memberBinding(
FragmentDetailBinding::inflate
)
protected var lastHolder: Highlightable? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
@ -47,12 +46,6 @@ abstract class DetailFragment : Fragment() {
callback.isEnabled = false
}
override fun onDestroyView() {
super.onDestroyView()
lastHolder = null
}
/**
* Shortcut method for doing setup of the detail toolbar.
*/

View file

@ -75,13 +75,31 @@ class AlbumDetailAdapter(
* Update the current song that this adapter should be watching for to highlight.
* @param song The [Song] to highlight if found, null to clear any highlighted ViewHolders
*/
fun setCurrentSong(song: Song?) {
fun highlightSong(song: Song?, recycler: RecyclerView) {
// Clear out the last ViewHolder as a song update usually signifies that this current
// ViewHolder is likely invalid.
lastHolder?.setHighlighted(false)
lastHolder = null
currentSong = song
if (song != null) {
// Use existing data instead of having to re-sort it.
val pos = currentList.indexOfFirst {
it.name == song.name && it is Song
}
// Check if the ViewHolder for this song is visible, if it is then highlight it.
// If the ViewHolder is not visible, then the adapter should take care of it if
// it does become visible.
recycler.layoutManager?.findViewByPosition(pos)?.let { child ->
recycler.getChildViewHolder(child)?.let {
lastHolder = it as Highlightable
lastHolder?.setHighlighted(true)
}
}
}
}
inner class AlbumHeaderViewHolder(

View file

@ -76,13 +76,29 @@ class ArtistDetailAdapter(
* Update the current album that this adapter should be watching for to highlight.
* @param album The [Album] to highlight if found, null to clear any highlighted ViewHolders
*/
fun setCurrentAlbum(album: Album?) {
fun setCurrentAlbum(album: Album?, recycler: RecyclerView) {
// Clear out the last ViewHolder as a song update usually signifies that this current
// ViewHolder is likely invalid.
lastHolder?.setHighlighted(false)
lastHolder = null
currentAlbum = album
if (album != null) {
// Use existing data instead of having to re-sort it.
val pos = currentList.indexOfFirst {
it.name == album.name && it is Album
}
// Check if the ViewHolder if this album is visible, and highlight it if so.
recycler.layoutManager?.findViewByPosition(pos)?.let { child ->
recycler.getChildViewHolder(child)?.let {
lastHolder = it as Highlightable
lastHolder?.setHighlighted(true)
}
}
}
}
inner class ArtistHeaderViewHolder(

View file

@ -59,7 +59,7 @@ data class Song(
/**
* Apply an album to a song.
* @throws IllegalArgumentException When a album is already applied.
* @throws IllegalArgumentException When an album is already applied.
*/
fun applyAlbum(album: Album) {
check(mAlbum == null) { "Album is already applied" }

View file

@ -43,7 +43,7 @@ fun NotificationManager.createMediaNotification(
context: Context,
mediaSession: MediaSessionCompat
): NotificationCompat.Builder {
// Create a notification channel if requireds
// Create a notification channel if required
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
NotificationUtils.CHANNEL_ID,

View file

@ -438,7 +438,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
* @param reason (Debug) The reason for this call.
*/
private fun startForegroundOrNotify(reason: String) {
// Don't start the foreground if:
// Don't start foreground if:
// - The playback hasnt even started
// - The playback hasnt been restored
// - There is nothing to play

View file

@ -130,7 +130,7 @@ class QueueFragment : Fragment() {
getString(R.string.label_all_songs)
} else {
if (playbackModel.parent.value is Genre) {
// Since t
// Use display name for Genres so that numbers dont show up
(playbackModel.parent.value as Genre).displayName
} else {
playbackModel.parent.value!!.name

View file

@ -118,8 +118,6 @@ class PlaybackStateManager private constructor() {
val isRestored: Boolean get() = mIsRestored
/** Whether this instance has started playing or not */
val hasPlayed: Boolean get() = mHasPlayed
/** Whether playback is in the user queue or not */
val isInUserQueue: Boolean get() = mIsInUserQueue
private val settingsManager = SettingsManager.getInstance()

View file

@ -14,7 +14,6 @@
style="@style/Toolbar.Style.Icon"
android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal"
app:contentInsetStartWithNavigation="0dp"
app:title="@string/label_library"
tools:menu="@menu/menu_artist_actions" />

View file

@ -34,6 +34,7 @@
<!-- Toolbar sub-style with a nav icon -->
<style name="Toolbar.Style.Icon" parent="Toolbar.Style">
<item name="navigationIcon">@drawable/ic_back</item>
<item name="contentInsetStartWithNavigation">0dp</item>
</style>
<!-- Toolbar sub-style with a fix for an odd search style -->