Make shared ViewHolders used defined types

Make the shared ViewHolders use their respective types instead of BaseModel.
This commit is contained in:
OxygenCobalt 2020-10-03 19:42:16 -06:00
parent 2126b4f78f
commit 7abb888108
6 changed files with 66 additions and 67 deletions

View file

@ -24,7 +24,6 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.theme.SHOW_ALBUMS
import org.oxycblt.auxio.theme.SHOW_ARTISTS
import org.oxycblt.auxio.theme.SHOW_GENRES
@ -44,14 +43,13 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
): View? {
val binding = FragmentLibraryBinding.inflate(inflater)
val libraryAdapter = LibraryAdapter(
libraryModel.showMode.value!!,
ClickListener { navToItem(it) }
)
val libraryAdapter = LibraryAdapter(libraryModel.showMode.value!!) {
navToItem(it)
}
val searchAdapter = SearchAdapter(
ClickListener { navToItem(it) }
)
val searchAdapter = SearchAdapter {
navToItem(it)
}
// Toolbar setup
binding.libraryToolbar.overflowIcon = ContextCompat.getDrawable(

View file

@ -23,7 +23,7 @@ class LibraryViewModel : ViewModel() {
val searchHasFocus: Boolean get() = mSearchHasFocus
// TODO: Move these to prefs when they're added
private val mShowMode = MutableLiveData(SHOW_ALBUMS)
private val mShowMode = MutableLiveData(SHOW_ARTISTS)
val showMode: LiveData<Int> get() = mShowMode
private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN)

View file

@ -18,9 +18,15 @@ import org.oxycblt.auxio.theme.SHOW_GENRES
// the showmode given. It cannot display multiple types of viewholders *at once*.
class LibraryAdapter(
private val showMode: Int,
val listener: ClickListener<BaseModel>
private val doOnClick: (BaseModel) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
// Create separate listeners for each type, as ClickListeners can be converted
// to a type-specific form.
private val genreListener = ClickListener<Genre> { doOnClick(it) }
private val artistListener = ClickListener<Artist> { doOnClick(it) }
private val albumListener = ClickListener<Album> { doOnClick(it) }
private var data: List<BaseModel>
init {
@ -39,10 +45,10 @@ class LibraryAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// Return a different View Holder depending on the show type
return when (showMode) {
SHOW_GENRES -> GenreViewHolder.from(parent.context, listener)
SHOW_ARTISTS -> ArtistViewHolder.from(parent.context, listener)
SHOW_ALBUMS -> AlbumViewHolder.from(parent.context, listener)
else -> ArtistViewHolder.from(parent.context, listener)
SHOW_GENRES -> GenreViewHolder.from(parent.context, genreListener)
SHOW_ARTISTS -> ArtistViewHolder.from(parent.context, artistListener)
SHOW_ALBUMS -> AlbumViewHolder.from(parent.context, albumListener)
else -> ArtistViewHolder.from(parent.context, artistListener)
}
}

View file

@ -18,8 +18,17 @@ import org.oxycblt.auxio.recycler.viewholders.HeaderViewHolder
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
class SearchAdapter(
private val listener: ClickListener<BaseModel>
private val doOnClick: (BaseModel) -> Unit
) : ListAdapter<BaseModel, RecyclerView.ViewHolder>(DiffCallback<BaseModel>()) {
// Create separate listeners for each type, as a BaseModel ClickListener cant be
// casted to a ClickListener of a class that inherits BaseModel.
// FIXME: Maybe theres a way for this to be improved?
private val genreListener = ClickListener<Genre> { doOnClick(it) }
private val artistListener = ClickListener<Artist> { doOnClick(it) }
private val albumListener = ClickListener<Album> { doOnClick(it) }
private val songListener = ClickListener<Song> { doOnClick(it) }
override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is Genre -> GenreViewHolder.ITEM_TYPE
@ -32,10 +41,10 @@ class SearchAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
GenreViewHolder.ITEM_TYPE -> GenreViewHolder.from(parent.context, listener)
ArtistViewHolder.ITEM_TYPE -> ArtistViewHolder.from(parent.context, listener)
AlbumViewHolder.ITEM_TYPE -> AlbumViewHolder.from(parent.context, listener)
SongViewHolder.ITEM_TYPE -> SongViewHolder.from(parent.context, listener)
GenreViewHolder.ITEM_TYPE -> GenreViewHolder.from(parent.context, genreListener)
ArtistViewHolder.ITEM_TYPE -> ArtistViewHolder.from(parent.context, artistListener)
AlbumViewHolder.ITEM_TYPE -> AlbumViewHolder.from(parent.context, albumListener)
SongViewHolder.ITEM_TYPE -> SongViewHolder.from(parent.context, songListener)
HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context)
else -> HeaderViewHolder.from(parent.context)
@ -44,13 +53,13 @@ class SearchAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is GenreViewHolder -> holder
is ArtistViewHolder -> holder
is AlbumViewHolder -> holder
is SongViewHolder -> holder
is HeaderViewHolder -> holder
is GenreViewHolder -> holder.bind(getItem(position) as Genre)
is ArtistViewHolder -> holder.bind(getItem(position) as Artist)
is AlbumViewHolder -> holder.bind(getItem(position) as Album)
is SongViewHolder -> holder.bind(getItem(position) as Song)
is HeaderViewHolder -> holder.bind(getItem(position) as Header)
else -> return
}.bind(getItem(position))
}
}
}

View file

@ -9,7 +9,6 @@ import org.oxycblt.auxio.databinding.ItemHeaderBinding
import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.music.Song
@ -19,19 +18,19 @@ import org.oxycblt.auxio.recycler.ClickListener
// FIXME: Mode these type signaturs to something sensible.
class GenreViewHolder private constructor(
listener: ClickListener<BaseModel>,
listener: ClickListener<Genre>,
private val binding: ItemGenreBinding
) : BaseViewHolder<BaseModel>(binding, listener) {
) : BaseViewHolder<Genre>(binding, listener) {
override fun onBind(model: BaseModel) {
binding.genre = model as Genre
override fun onBind(model: Genre) {
binding.genre = model
binding.genreName.requestLayout()
}
companion object {
const val ITEM_TYPE = 10
fun from(context: Context, listener: ClickListener<BaseModel>): GenreViewHolder {
fun from(context: Context, listener: ClickListener<Genre>): GenreViewHolder {
return GenreViewHolder(
ClickListener { listener.onClick(it) },
ItemGenreBinding.inflate(LayoutInflater.from(context))
@ -41,19 +40,19 @@ class GenreViewHolder private constructor(
}
class ArtistViewHolder private constructor(
listener: ClickListener<BaseModel>,
listener: ClickListener<Artist>,
private val binding: ItemArtistBinding
) : BaseViewHolder<BaseModel>(binding, listener) {
) : BaseViewHolder<Artist>(binding, listener) {
override fun onBind(model: BaseModel) {
binding.artist = model as Artist
override fun onBind(model: Artist) {
binding.artist = model
binding.artistName.requestLayout()
}
companion object {
const val ITEM_TYPE = 11
fun from(context: Context, listener: ClickListener<BaseModel>): ArtistViewHolder {
fun from(context: Context, listener: ClickListener<Artist>): ArtistViewHolder {
return ArtistViewHolder(
ClickListener { listener.onClick(it) },
ItemArtistBinding.inflate(LayoutInflater.from(context))
@ -63,19 +62,19 @@ class ArtistViewHolder private constructor(
}
class AlbumViewHolder private constructor(
listener: ClickListener<BaseModel>,
listener: ClickListener<Album>,
private val binding: ItemAlbumBinding
) : BaseViewHolder<BaseModel>(binding, listener) {
) : BaseViewHolder<Album>(binding, listener) {
override fun onBind(model: BaseModel) {
binding.album = model as Album
override fun onBind(model: Album) {
binding.album = model
binding.albumName.requestLayout()
}
companion object {
const val ITEM_TYPE = 12
fun from(context: Context, listener: ClickListener<BaseModel>): AlbumViewHolder {
fun from(context: Context, listener: ClickListener<Album>): AlbumViewHolder {
return AlbumViewHolder(
listener,
ItemAlbumBinding.inflate(LayoutInflater.from(context))
@ -85,12 +84,12 @@ class AlbumViewHolder private constructor(
}
class SongViewHolder private constructor(
listener: ClickListener<BaseModel>,
listener: ClickListener<Song>,
private val binding: ItemSongBinding
) : BaseViewHolder<BaseModel>(binding, listener) {
) : BaseViewHolder<Song>(binding, listener) {
override fun onBind(model: BaseModel) {
binding.song = model as Song
override fun onBind(model: Song) {
binding.song = model
binding.songName.requestLayout()
binding.songInfo.requestLayout()
@ -99,7 +98,7 @@ class SongViewHolder private constructor(
companion object {
const val ITEM_TYPE = 13
fun from(context: Context, listener: ClickListener<BaseModel>): SongViewHolder {
fun from(context: Context, listener: ClickListener<Song>): SongViewHolder {
return SongViewHolder(
listener,
ItemSongBinding.inflate(LayoutInflater.from(context))
@ -110,9 +109,9 @@ class SongViewHolder private constructor(
class HeaderViewHolder(
private val binding: ItemHeaderBinding
) : BaseViewHolder<BaseModel>(binding, null) {
override fun onBind(model: BaseModel) {
binding.header = model as Header
) : BaseViewHolder<Header>(binding, null) {
override fun onBind(model: Header) {
binding.header = model
}
companion object {

View file

@ -7,33 +7,20 @@ import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
class SongAdapter(
private val data: List<Song>,
private val listener: ClickListener<Song>
) : RecyclerView.Adapter<SongAdapter.ViewHolder>() {
) : RecyclerView.Adapter<SongViewHolder>() {
override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
ItemSongBinding.inflate(LayoutInflater.from(parent.context))
)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
return SongViewHolder.from(parent.context, listener)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
holder.bind(data[position])
}
inner class ViewHolder(
private val binding: ItemSongBinding
) : BaseViewHolder<Song>(binding, listener) {
override fun onBind(model: Song) {
binding.song = model
binding.songName.requestLayout()
binding.songInfo.requestLayout()
}
}
}