From f866e77ee42a4279e0d25f014f083a569adaa2a5 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sun, 27 Sep 2020 11:13:24 -0600 Subject: [PATCH] Add parent ViewHolder Add an base ViewHolder class so that there isnt as much repeated code. --- AuxioTODO | 2 -- .../detail/adapters/DetailAlbumAdapter.kt | 23 +++------------- .../detail/adapters/DetailArtistAdapter.kt | 25 ++++-------------- .../detail/adapters/DetailSongAdapter.kt | 23 +++------------- .../oxycblt/auxio/library/LibraryFragment.kt | 2 +- .../auxio/library/adapters/AlbumAdapter.kt | 23 +++------------- .../auxio/library/adapters/ArtistAdapter.kt | 21 +++------------ .../auxio/library/adapters/GenreAdapter.kt | 21 +++------------ .../auxio/music/{Models.kt => MusicModels.kt} | 0 .../oxycblt/auxio/recycler/RecyclerUtils.kt | 26 ++++++++++++++++++- .../org/oxycblt/auxio/songs/SongAdapter.kt | 24 +++-------------- 11 files changed, 55 insertions(+), 135 deletions(-) rename app/src/main/java/org/oxycblt/auxio/music/{Models.kt => MusicModels.kt} (100%) diff --git a/AuxioTODO b/AuxioTODO index 9199d6afd..94d434c18 100644 --- a/AuxioTODO +++ b/AuxioTODO @@ -33,9 +33,7 @@ TODO: /other/ -- Create inherited adapter/viewholder so I dont have to repeat as much code - ? Condense detail fragments into a single fragment ? -- Make data items inherit a single class - Condense artist/album recyclerview items into single item - Remove binding adapters diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailAlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailAlbumAdapter.kt index 5abf4a796..f8cf9ed9c 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailAlbumAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailAlbumAdapter.kt @@ -3,9 +3,9 @@ package org.oxycblt.auxio.detail.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding import org.oxycblt.auxio.music.Album +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.DiffCallback @@ -26,26 +26,11 @@ class DetailAlbumAdapter( // Generic ViewHolder for an album inner class ViewHolder( private val binding: ItemArtistAlbumBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(album: Album) { - binding.album = album - - binding.root.setOnClickListener { - listener.onClick(album) - } - - // Force-update the layout so ellipsizing works. + override fun onBind(model: Album) { + binding.album = model binding.albumName.requestLayout() - binding.executePendingBindings() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailArtistAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailArtistAdapter.kt index 8088e7479..7b6a2ac0d 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailArtistAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailArtistAdapter.kt @@ -3,9 +3,9 @@ package org.oxycblt.auxio.detail.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemGenreArtistBinding import org.oxycblt.auxio.music.Artist +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.DiffCallback @@ -26,26 +26,11 @@ class DetailArtistAdapter( // Generic ViewHolder for an album inner class ViewHolder( private val binding: ItemGenreArtistBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(artist: Artist) { - binding.artist = artist - - binding.root.setOnClickListener { - listener.onClick(artist) - } - - // Force-update the layout so ellipsizing works. - binding.artistImage.requestLayout() - binding.executePendingBindings() + override fun onBind(model: Artist) { + binding.artist = model + binding.artistName.requestLayout() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailSongAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailSongAdapter.kt index 32b479bc7..025c9a2be 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailSongAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/DetailSongAdapter.kt @@ -3,9 +3,9 @@ package org.oxycblt.auxio.detail.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemAlbumSongBinding import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.DiffCallback @@ -26,26 +26,11 @@ class DetailSongAdapter( // Generic ViewHolder for a song inner class ViewHolder( private val binding: ItemAlbumSongBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(song: Song) { - binding.song = song - - binding.root.setOnClickListener { - listener.onClick(song) - } - - // Force-update the layout so ellipsizing works. + override fun onBind(model: Song) { + binding.song = model binding.songName.requestLayout() - binding.executePendingBindings() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt index 35123dbdd..1af6d992a 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt @@ -26,7 +26,7 @@ import org.oxycblt.auxio.theme.applyDivider class LibraryFragment : Fragment() { // FIXME: Temp value, remove when there are actual preferences - private val libraryMode = SHOW_GENRES + private val libraryMode = SHOW_ARTISTS private val musicModel: MusicViewModel by activityViewModels() private val libraryModel: LibraryViewModel by activityViewModels() diff --git a/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt index e5884d2e0..3d3fd3936 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemAlbumBinding import org.oxycblt.auxio.music.Album +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener class AlbumAdapter( @@ -24,29 +25,13 @@ class AlbumAdapter( holder.bind(data[position]) } - // Generic ViewHolder for an album inner class ViewHolder( private val binding: ItemAlbumBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(album: Album) { - binding.album = album - - binding.root.setOnClickListener { - listener.onClick(album) - } - - // Force-update the layout so ellipsizing works. + override fun onBind(model: Album) { + binding.album = model binding.albumName.requestLayout() - binding.executePendingBindings() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt b/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt index b9e5ce5dd..f54bafeba 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemArtistBinding import org.oxycblt.auxio.music.Artist +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener class ArtistAdapter( @@ -24,27 +25,13 @@ class ArtistAdapter( holder.bind(data[position]) } - // Generic ViewHolder for an artist inner class ViewHolder( private val binding: ItemArtistBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(artist: Artist) { - binding.artist = artist - - binding.root.setOnClickListener { listener.onClick(artist) } - - // Force-update the layout so ellipsizing works. + override fun onBind(model: Artist) { + binding.artist = model binding.artistName.requestLayout() - binding.executePendingBindings() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/library/adapters/GenreAdapter.kt b/app/src/main/java/org/oxycblt/auxio/library/adapters/GenreAdapter.kt index ba287667d..c4e0502f4 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/adapters/GenreAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/adapters/GenreAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemGenreBinding import org.oxycblt.auxio.music.Genre +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener class GenreAdapter( @@ -24,27 +25,13 @@ class GenreAdapter( holder.bind(data[position]) } - // Generic ViewHolder for an artist inner class ViewHolder( private val binding: ItemGenreBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(genre: Genre) { - binding.genre = genre - - binding.root.setOnClickListener { listener.onClick(genre) } - - // Force-update the layout so ellipsizing works. + override fun onBind(model: Genre) { + binding.genre = model binding.artistName.requestLayout() - binding.executePendingBindings() } } } diff --git a/app/src/main/java/org/oxycblt/auxio/music/Models.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicModels.kt similarity index 100% rename from app/src/main/java/org/oxycblt/auxio/music/Models.kt rename to app/src/main/java/org/oxycblt/auxio/music/MusicModels.kt diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/RecyclerUtils.kt b/app/src/main/java/org/oxycblt/auxio/recycler/RecyclerUtils.kt index 001d4314f..a20084d14 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/RecyclerUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/RecyclerUtils.kt @@ -1,6 +1,8 @@ package org.oxycblt.auxio.recycler +import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.R import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist @@ -10,7 +12,7 @@ import org.oxycblt.auxio.music.Song // RecyclerView click listener class ClickListener(val onClick: (T) -> Unit) -// Song Diff callback +// Base Diff callback class DiffCallback : DiffUtil.ItemCallback() { override fun areContentsTheSame(oldItem: T, newItem: T): Boolean { return oldItem.id == newItem.id @@ -21,6 +23,28 @@ class DiffCallback : DiffUtil.ItemCallback() { } } +// ViewHolder abstraction that automates some of the things that are common for all ViewHolders. +abstract class BaseViewHolder( + private val baseBinding: ViewDataBinding, + protected val listener: ClickListener +) : RecyclerView.ViewHolder(baseBinding.root) { + init { + baseBinding.root.layoutParams = RecyclerView.LayoutParams( + RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT + ) + } + + fun bind(model: T) { + baseBinding.root.setOnClickListener { listener.onClick(model) } + + onBind(model) + + baseBinding.executePendingBindings() + } + + abstract fun onBind(model: T) +} + // Sorting modes enum class SortMode(val iconRes: Int) { // Icons for each mode are assigned to the enums themselves diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt index bc4bf5e25..425dfd3ff 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.databinding.ItemSongBinding import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.recycler.BaseViewHolder import org.oxycblt.auxio.recycler.ClickListener class SongAdapter( @@ -24,31 +25,14 @@ class SongAdapter( holder.bind(data[position]) } - // Generic ViewHolder for an album inner class ViewHolder( private val binding: ItemSongBinding - ) : RecyclerView.ViewHolder(binding.root) { + ) : BaseViewHolder(binding, listener) { - init { - // Force the viewholder to *actually* be the screen width so ellipsizing can work. - binding.root.layoutParams = RecyclerView.LayoutParams( - RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT - ) - } - - // Bind the view w/new data - fun bind(song: Song) { - binding.song = song - - binding.root.setOnClickListener { - listener.onClick(song) - } - - // Force-update the layouts so ellipsizing works. + override fun onBind(model: Song) { + binding.song = model binding.songName.requestLayout() binding.songInfo.requestLayout() - - binding.executePendingBindings() } } }