Update ViewHolder structure
Move all shared viewholders to /recycler/, and change structure of shared viewholders to prohibit direct instantiation.
This commit is contained in:
parent
45f411fdd7
commit
2126b4f78f
15 changed files with 186 additions and 166 deletions
|
@ -67,6 +67,8 @@ class AlbumDetailFragment : Fragment() {
|
||||||
// If the album was shown directly from LibraryFragment, Then enable the ability to
|
// If the album was shown directly from LibraryFragment, Then enable the ability to
|
||||||
// navigate upwards to the parent artist
|
// navigate upwards to the parent artist
|
||||||
if (args.enableParentNav) {
|
if (args.enableParentNav) {
|
||||||
|
detailModel.doneWithNavToParent()
|
||||||
|
|
||||||
detailModel.navToParent.observe(viewLifecycleOwner) {
|
detailModel.navToParent.observe(viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
|
|
|
@ -5,9 +5,9 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding
|
import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.recycler.BaseViewHolder
|
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class DetailAlbumAdapter(
|
class DetailAlbumAdapter(
|
||||||
private val listener: ClickListener<Album>
|
private val listener: ClickListener<Album>
|
||||||
|
@ -23,7 +23,7 @@ class DetailAlbumAdapter(
|
||||||
holder.bind(getItem(position))
|
holder.bind(getItem(position))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic ViewHolder for an album
|
// Generic ViewHolder for a detail album
|
||||||
inner class ViewHolder(
|
inner class ViewHolder(
|
||||||
private val binding: ItemArtistAlbumBinding
|
private val binding: ItemArtistAlbumBinding
|
||||||
) : BaseViewHolder<Album>(binding, listener) {
|
) : BaseViewHolder<Album>(binding, listener) {
|
||||||
|
|
|
@ -5,9 +5,9 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import org.oxycblt.auxio.databinding.ItemGenreArtistBinding
|
import org.oxycblt.auxio.databinding.ItemGenreArtistBinding
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.recycler.BaseViewHolder
|
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class DetailArtistAdapter(
|
class DetailArtistAdapter(
|
||||||
private val listener: ClickListener<Artist>
|
private val listener: ClickListener<Artist>
|
||||||
|
|
|
@ -5,9 +5,9 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
|
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.recycler.BaseViewHolder
|
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class DetailSongAdapter(
|
class DetailSongAdapter(
|
||||||
private val listener: ClickListener<Song>
|
private val listener: ClickListener<Song>
|
||||||
|
|
|
@ -23,7 +23,7 @@ class LibraryViewModel : ViewModel() {
|
||||||
val searchHasFocus: Boolean get() = mSearchHasFocus
|
val searchHasFocus: Boolean get() = mSearchHasFocus
|
||||||
|
|
||||||
// TODO: Move these to prefs when they're added
|
// TODO: Move these to prefs when they're added
|
||||||
private val mShowMode = MutableLiveData(SHOW_ARTISTS)
|
private val mShowMode = MutableLiveData(SHOW_ALBUMS)
|
||||||
val showMode: LiveData<Int> get() = mShowMode
|
val showMode: LiveData<Int> get() = mShowMode
|
||||||
|
|
||||||
private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN)
|
private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN)
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package org.oxycblt.auxio.library.recycler
|
package org.oxycblt.auxio.library.recycler
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.oxycblt.auxio.databinding.ItemAlbumBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemArtistBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemGenreBinding
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
|
||||||
import org.oxycblt.auxio.theme.SHOW_ALBUMS
|
import org.oxycblt.auxio.theme.SHOW_ALBUMS
|
||||||
import org.oxycblt.auxio.theme.SHOW_ARTISTS
|
import org.oxycblt.auxio.theme.SHOW_ARTISTS
|
||||||
import org.oxycblt.auxio.theme.SHOW_GENRES
|
import org.oxycblt.auxio.theme.SHOW_GENRES
|
||||||
|
|
||||||
// A Great Value androidx ListAdapter that can display three types of ViewHolders.
|
// A ListAdapter that can contain three different types of ViewHolders depending
|
||||||
|
// the showmode given. It cannot display multiple types of viewholders *at once*.
|
||||||
class LibraryAdapter(
|
class LibraryAdapter(
|
||||||
private val showMode: Int,
|
private val showMode: Int,
|
||||||
val listener: ClickListener<BaseModel>
|
val listener: ClickListener<BaseModel>
|
||||||
|
@ -39,36 +39,21 @@ class LibraryAdapter(
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
// Return a different View Holder depending on the show type
|
// Return a different View Holder depending on the show type
|
||||||
return when (showMode) {
|
return when (showMode) {
|
||||||
SHOW_GENRES -> GenreViewHolder(
|
SHOW_GENRES -> GenreViewHolder.from(parent.context, listener)
|
||||||
listener,
|
SHOW_ARTISTS -> ArtistViewHolder.from(parent.context, listener)
|
||||||
ItemGenreBinding.inflate(LayoutInflater.from(parent.context))
|
SHOW_ALBUMS -> AlbumViewHolder.from(parent.context, listener)
|
||||||
)
|
else -> ArtistViewHolder.from(parent.context, listener)
|
||||||
|
|
||||||
SHOW_ARTISTS -> ArtistViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemArtistBinding.inflate(LayoutInflater.from(parent.context))
|
|
||||||
)
|
|
||||||
|
|
||||||
SHOW_ALBUMS -> AlbumViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemAlbumBinding.inflate(LayoutInflater.from(parent.context))
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> ArtistViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemArtistBinding.inflate(LayoutInflater.from(parent.context))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
when (showMode) {
|
when (showMode) {
|
||||||
SHOW_GENRES -> holder as GenreViewHolder
|
SHOW_GENRES -> (holder as GenreViewHolder).bind(data[position] as Genre)
|
||||||
SHOW_ARTISTS -> holder as ArtistViewHolder
|
SHOW_ARTISTS -> (holder as ArtistViewHolder).bind(data[position] as Artist)
|
||||||
SHOW_ALBUMS -> holder as AlbumViewHolder
|
SHOW_ALBUMS -> (holder as AlbumViewHolder).bind(data[position] as Album)
|
||||||
|
|
||||||
else -> return
|
else -> return
|
||||||
}.bind(data[position])
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the data, as its an internal value.
|
// Update the data, as its an internal value.
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
package org.oxycblt.auxio.library.recycler
|
package org.oxycblt.auxio.library.recycler
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.oxycblt.auxio.databinding.ItemAlbumBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemArtistBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemGenreBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemHeaderBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemSongBinding
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
@ -17,62 +11,34 @@ import org.oxycblt.auxio.music.Header
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.HeaderViewHolder
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
private val listener: ClickListener<BaseModel>
|
private val listener: ClickListener<BaseModel>
|
||||||
) : ListAdapter<BaseModel, RecyclerView.ViewHolder>(DiffCallback<BaseModel>()) {
|
) : ListAdapter<BaseModel, RecyclerView.ViewHolder>(DiffCallback<BaseModel>()) {
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return when (getItem(position)) {
|
return when (getItem(position)) {
|
||||||
is Genre -> ITEM_TYPE_GENRE
|
is Genre -> GenreViewHolder.ITEM_TYPE
|
||||||
is Artist -> ITEM_TYPE_ARTIST
|
is Artist -> ArtistViewHolder.ITEM_TYPE
|
||||||
is Album -> ITEM_TYPE_ALBUM
|
is Album -> AlbumViewHolder.ITEM_TYPE
|
||||||
is Song -> ITEM_TYPE_SONG
|
is Song -> SongViewHolder.ITEM_TYPE
|
||||||
is Header -> ITEM_TYPE_HEADER
|
is Header -> HeaderViewHolder.ITEM_TYPE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
ITEM_TYPE_GENRE -> GenreViewHolder(
|
GenreViewHolder.ITEM_TYPE -> GenreViewHolder.from(parent.context, listener)
|
||||||
listener,
|
ArtistViewHolder.ITEM_TYPE -> ArtistViewHolder.from(parent.context, listener)
|
||||||
ItemGenreBinding.inflate(
|
AlbumViewHolder.ITEM_TYPE -> AlbumViewHolder.from(parent.context, listener)
|
||||||
LayoutInflater.from(parent.context)
|
SongViewHolder.ITEM_TYPE -> SongViewHolder.from(parent.context, listener)
|
||||||
)
|
HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context)
|
||||||
)
|
|
||||||
|
|
||||||
ITEM_TYPE_ARTIST -> ArtistViewHolder(
|
else -> HeaderViewHolder.from(parent.context)
|
||||||
listener,
|
|
||||||
ItemArtistBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
ITEM_TYPE_ALBUM -> AlbumViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemAlbumBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
ITEM_TYPE_SONG -> SongViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemSongBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
ITEM_TYPE_HEADER -> HeaderViewHolder(
|
|
||||||
ItemHeaderBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> ArtistViewHolder(
|
|
||||||
listener,
|
|
||||||
ItemArtistBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +51,6 @@ class SearchAdapter(
|
||||||
is HeaderViewHolder -> holder
|
is HeaderViewHolder -> holder
|
||||||
|
|
||||||
else -> return
|
else -> return
|
||||||
}.onBind(getItem(position))
|
}.bind(getItem(position))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package org.oxycblt.auxio.library.recycler
|
|
||||||
|
|
||||||
import org.oxycblt.auxio.databinding.ItemAlbumBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemArtistBinding
|
|
||||||
import org.oxycblt.auxio.databinding.ItemGenreBinding
|
|
||||||
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
|
|
||||||
import org.oxycblt.auxio.recycler.BaseViewHolder
|
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
|
||||||
|
|
||||||
const val ITEM_TYPE_GENRE = 10
|
|
||||||
const val ITEM_TYPE_ARTIST = 11
|
|
||||||
const val ITEM_TYPE_ALBUM = 12
|
|
||||||
const val ITEM_TYPE_SONG = 13
|
|
||||||
const val ITEM_TYPE_HEADER = 14
|
|
||||||
|
|
||||||
class GenreViewHolder(
|
|
||||||
listener: ClickListener<BaseModel>,
|
|
||||||
private val binding: ItemGenreBinding
|
|
||||||
) : BaseViewHolder<BaseModel>(binding, listener) {
|
|
||||||
|
|
||||||
override fun onBind(model: BaseModel) {
|
|
||||||
binding.genre = model as Genre
|
|
||||||
binding.genreName.requestLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ArtistViewHolder(
|
|
||||||
listener: ClickListener<BaseModel>,
|
|
||||||
private val binding: ItemArtistBinding
|
|
||||||
) : BaseViewHolder<BaseModel>(binding, listener) {
|
|
||||||
|
|
||||||
override fun onBind(model: BaseModel) {
|
|
||||||
binding.artist = model as Artist
|
|
||||||
binding.artistName.requestLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AlbumViewHolder(
|
|
||||||
listener: ClickListener<BaseModel>,
|
|
||||||
private val binding: ItemAlbumBinding
|
|
||||||
) : BaseViewHolder<BaseModel>(binding, listener) {
|
|
||||||
|
|
||||||
override fun onBind(model: BaseModel) {
|
|
||||||
binding.album = model as Album
|
|
||||||
binding.albumName.requestLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SongViewHolder(
|
|
||||||
listener: ClickListener<BaseModel>,
|
|
||||||
private val binding: ItemSongBinding
|
|
||||||
) : BaseViewHolder<BaseModel>(binding, listener) {
|
|
||||||
|
|
||||||
override fun onBind(model: BaseModel) {
|
|
||||||
binding.song = model as Song
|
|
||||||
|
|
||||||
binding.songName.requestLayout()
|
|
||||||
binding.songInfo.requestLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HeaderViewHolder(
|
|
||||||
private val binding: ItemHeaderBinding
|
|
||||||
) : BaseViewHolder<BaseModel>(binding, null) {
|
|
||||||
override fun onBind(model: BaseModel) {
|
|
||||||
binding.header = model as Header
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -131,7 +131,7 @@ fun TextView.bindArtistCounts(artist: Artist) {
|
||||||
|
|
||||||
// Get a bunch of miscellaneous album information [Year, Songs, Duration] and combine them
|
// Get a bunch of miscellaneous album information [Year, Songs, Duration] and combine them
|
||||||
@BindingAdapter("albumDetails")
|
@BindingAdapter("albumDetails")
|
||||||
fun TextView.bindAlbumDetails(album: Album) {
|
fun TextView.bindAllAlbumDetails(album: Album) {
|
||||||
text = context.getString(
|
text = context.getString(
|
||||||
R.string.format_double_info,
|
R.string.format_double_info,
|
||||||
album.year.toYear(context),
|
album.year.toYear(context),
|
||||||
|
@ -143,6 +143,18 @@ fun TextView.bindAlbumDetails(album: Album) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("albumInfo")
|
||||||
|
fun TextView.bindAlbumInfo(album: Album) {
|
||||||
|
text = context.getString(
|
||||||
|
R.string.format_info,
|
||||||
|
album.artist.name,
|
||||||
|
context.resources.getQuantityString(
|
||||||
|
R.plurals.format_song_count,
|
||||||
|
album.numSongs, album.numSongs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@BindingAdapter("albumYear")
|
@BindingAdapter("albumYear")
|
||||||
fun TextView.bindAlbumDate(album: Album) {
|
fun TextView.bindAlbumDate(album: Album) {
|
||||||
text = album.year.toYear(context)
|
text = album.year.toYear(context)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import androidx.recyclerview.widget.DiffUtil
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
|
||||||
// RecyclerView click listener
|
// RecyclerView click listener
|
||||||
class ClickListener<T>(val onClick: (T) -> Unit)
|
class ClickListener<T : BaseModel>(val onClick: (T) -> Unit)
|
||||||
|
|
||||||
// Base Diff callback
|
// Base Diff callback
|
||||||
class DiffCallback<T : BaseModel> : DiffUtil.ItemCallback<T>() {
|
class DiffCallback<T : BaseModel> : DiffUtil.ItemCallback<T>() {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package org.oxycblt.auxio.recycler
|
package org.oxycblt.auxio.recycler.viewholders
|
||||||
|
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
|
|
||||||
// ViewHolder abstraction that automates some of the things that are common for all ViewHolders.
|
// ViewHolder abstraction that automates some of the things that are common for all ViewHolders.
|
||||||
|
// TODO: Implement some kind of abstraction for BaseViewHolder.from()
|
||||||
abstract class BaseViewHolder<T : BaseModel>(
|
abstract class BaseViewHolder<T : BaseModel>(
|
||||||
private val baseBinding: ViewDataBinding,
|
private val baseBinding: ViewDataBinding,
|
||||||
protected val listener: ClickListener<T>?
|
protected val listener: ClickListener<T>?
|
|
@ -0,0 +1,127 @@
|
||||||
|
package org.oxycblt.auxio.recycler.viewholders
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import org.oxycblt.auxio.databinding.ItemAlbumBinding
|
||||||
|
import org.oxycblt.auxio.databinding.ItemArtistBinding
|
||||||
|
import org.oxycblt.auxio.databinding.ItemGenreBinding
|
||||||
|
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
|
||||||
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
|
|
||||||
|
// Basic ViewHolders for each music model.
|
||||||
|
// FIXME: Mode these type signaturs to something sensible.
|
||||||
|
|
||||||
|
class GenreViewHolder private constructor(
|
||||||
|
listener: ClickListener<BaseModel>,
|
||||||
|
private val binding: ItemGenreBinding
|
||||||
|
) : BaseViewHolder<BaseModel>(binding, listener) {
|
||||||
|
|
||||||
|
override fun onBind(model: BaseModel) {
|
||||||
|
binding.genre = model as Genre
|
||||||
|
binding.genreName.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ITEM_TYPE = 10
|
||||||
|
|
||||||
|
fun from(context: Context, listener: ClickListener<BaseModel>): GenreViewHolder {
|
||||||
|
return GenreViewHolder(
|
||||||
|
ClickListener { listener.onClick(it) },
|
||||||
|
ItemGenreBinding.inflate(LayoutInflater.from(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArtistViewHolder private constructor(
|
||||||
|
listener: ClickListener<BaseModel>,
|
||||||
|
private val binding: ItemArtistBinding
|
||||||
|
) : BaseViewHolder<BaseModel>(binding, listener) {
|
||||||
|
|
||||||
|
override fun onBind(model: BaseModel) {
|
||||||
|
binding.artist = model as Artist
|
||||||
|
binding.artistName.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ITEM_TYPE = 11
|
||||||
|
|
||||||
|
fun from(context: Context, listener: ClickListener<BaseModel>): ArtistViewHolder {
|
||||||
|
return ArtistViewHolder(
|
||||||
|
ClickListener { listener.onClick(it) },
|
||||||
|
ItemArtistBinding.inflate(LayoutInflater.from(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlbumViewHolder private constructor(
|
||||||
|
listener: ClickListener<BaseModel>,
|
||||||
|
private val binding: ItemAlbumBinding
|
||||||
|
) : BaseViewHolder<BaseModel>(binding, listener) {
|
||||||
|
|
||||||
|
override fun onBind(model: BaseModel) {
|
||||||
|
binding.album = model as Album
|
||||||
|
binding.albumName.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ITEM_TYPE = 12
|
||||||
|
|
||||||
|
fun from(context: Context, listener: ClickListener<BaseModel>): AlbumViewHolder {
|
||||||
|
return AlbumViewHolder(
|
||||||
|
listener,
|
||||||
|
ItemAlbumBinding.inflate(LayoutInflater.from(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SongViewHolder private constructor(
|
||||||
|
listener: ClickListener<BaseModel>,
|
||||||
|
private val binding: ItemSongBinding
|
||||||
|
) : BaseViewHolder<BaseModel>(binding, listener) {
|
||||||
|
|
||||||
|
override fun onBind(model: BaseModel) {
|
||||||
|
binding.song = model as Song
|
||||||
|
|
||||||
|
binding.songName.requestLayout()
|
||||||
|
binding.songInfo.requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ITEM_TYPE = 13
|
||||||
|
|
||||||
|
fun from(context: Context, listener: ClickListener<BaseModel>): SongViewHolder {
|
||||||
|
return SongViewHolder(
|
||||||
|
listener,
|
||||||
|
ItemSongBinding.inflate(LayoutInflater.from(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeaderViewHolder(
|
||||||
|
private val binding: ItemHeaderBinding
|
||||||
|
) : BaseViewHolder<BaseModel>(binding, null) {
|
||||||
|
override fun onBind(model: BaseModel) {
|
||||||
|
binding.header = model as Header
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ITEM_TYPE = 14
|
||||||
|
|
||||||
|
fun from(context: Context): HeaderViewHolder {
|
||||||
|
return HeaderViewHolder(
|
||||||
|
ItemHeaderBinding.inflate(LayoutInflater.from(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,8 +5,8 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.oxycblt.auxio.databinding.ItemSongBinding
|
import org.oxycblt.auxio.databinding.ItemSongBinding
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.recycler.BaseViewHolder
|
|
||||||
import org.oxycblt.auxio.recycler.ClickListener
|
import org.oxycblt.auxio.recycler.ClickListener
|
||||||
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class SongAdapter(
|
class SongAdapter(
|
||||||
private val data: List<Song>,
|
private val data: List<Song>,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.oxycblt.auxio.theme
|
package org.oxycblt.auxio.theme
|
||||||
|
|
||||||
// Preference Constants
|
// Preference Constants
|
||||||
|
// TODO: Move these to dedicated enum class.
|
||||||
const val SHOW_ARTISTS = 0
|
const val SHOW_ARTISTS = 0
|
||||||
const val SHOW_ALBUMS = 1
|
const val SHOW_ALBUMS = 1
|
||||||
const val SHOW_GENRES = 2
|
const val SHOW_GENRES = 2
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/album_song_count"
|
app:layout_constraintBottom_toTopOf="@+id/album_info"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
@ -47,14 +47,14 @@
|
||||||
tools:text="Album Name" />
|
tools:text="Album Name" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/album_song_count"
|
android:id="@+id/album_info"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
app:albumSongCount="@{album}"
|
app:albumInfo="@{album}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
||||||
|
|
Loading…
Reference in a new issue