Update BaseViewHolder

Change the name of BaseViewHolder to BaseHolder and make the click listener arguments optional.
This commit is contained in:
OxygenCobalt 2021-02-07 14:00:48 -07:00
parent 23ddfd4d99
commit cef4cb68da
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
8 changed files with 48 additions and 47 deletions

View file

@ -1,6 +1,5 @@
package org.oxycblt.auxio.detail.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
@ -14,11 +13,12 @@ import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.BaseHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.applyAccents
import org.oxycblt.auxio.ui.disable
import org.oxycblt.auxio.ui.inflater
import org.oxycblt.auxio.ui.setTextColorResource
/**
@ -46,10 +46,10 @@ class AlbumDetailAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ALBUM_HEADER_ITEM_TYPE -> AlbumHeaderViewHolder(
ItemAlbumHeaderBinding.inflate(LayoutInflater.from(parent.context))
ItemAlbumHeaderBinding.inflate(parent.context.inflater)
)
ALBUM_SONG_ITEM_TYPE -> AlbumSongViewHolder(
ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context))
ItemAlbumSongBinding.inflate(parent.context.inflater)
)
else -> error("Invalid ViewHolder item type $viewType")
@ -107,7 +107,7 @@ class AlbumDetailAdapter(
inner class AlbumHeaderViewHolder(
private val binding: ItemAlbumHeaderBinding
) : BaseViewHolder<Album>(binding, null, null) {
) : BaseHolder<Album>(binding) {
override fun onBind(data: Album) {
binding.album = data
@ -126,7 +126,7 @@ class AlbumDetailAdapter(
inner class AlbumSongViewHolder(
private val binding: ItemAlbumSongBinding,
) : BaseViewHolder<Song>(binding, doOnClick, doOnLongClick), Highlightable {
) : BaseHolder<Song>(binding, doOnClick, doOnLongClick), Highlightable {
private val normalTextColor = binding.songName.currentTextColor
private val inactiveTextColor = binding.songTrack.currentTextColor

View file

@ -1,6 +1,5 @@
package org.oxycblt.auxio.detail.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
@ -14,11 +13,12 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.BaseHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.applyAccents
import org.oxycblt.auxio.ui.disable
import org.oxycblt.auxio.ui.inflater
import org.oxycblt.auxio.ui.setTextColorResource
/**
@ -46,11 +46,11 @@ class ArtistDetailAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ARTIST_HEADER_ITEM_TYPE -> ArtistHeaderViewHolder(
ItemArtistHeaderBinding.inflate(LayoutInflater.from(parent.context))
ItemArtistHeaderBinding.inflate(parent.context.inflater)
)
ARTIST_ALBUM_ITEM_TYPE -> ArtistAlbumViewHolder(
ItemArtistAlbumBinding.inflate(LayoutInflater.from(parent.context))
ItemArtistAlbumBinding.inflate(parent.context.inflater)
)
else -> error("Invalid ViewHolder item type $viewType")
@ -106,7 +106,7 @@ class ArtistDetailAdapter(
inner class ArtistHeaderViewHolder(
private val binding: ItemArtistHeaderBinding
) : BaseViewHolder<Artist>(binding, null, null) {
) : BaseHolder<Artist>(binding) {
override fun onBind(data: Artist) {
binding.artist = data
@ -126,7 +126,7 @@ class ArtistDetailAdapter(
// Generic ViewHolder for a detail album
inner class ArtistAlbumViewHolder(
private val binding: ItemArtistAlbumBinding,
) : BaseViewHolder<Album>(binding, doOnClick, doOnLongClick), Highlightable {
) : BaseHolder<Album>(binding, doOnClick, doOnLongClick), Highlightable {
private val normalTextColor = binding.albumName.currentTextColor
override fun onBind(data: Album) {

View file

@ -1,6 +1,5 @@
package org.oxycblt.auxio.detail.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
@ -14,11 +13,12 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.BaseHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.applyAccents
import org.oxycblt.auxio.ui.disable
import org.oxycblt.auxio.ui.inflater
import org.oxycblt.auxio.ui.setTextColorResource
/**
@ -47,11 +47,11 @@ class GenreDetailAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
GENRE_HEADER_ITEM_TYPE -> GenreHeaderViewHolder(
ItemGenreHeaderBinding.inflate(LayoutInflater.from(parent.context))
ItemGenreHeaderBinding.inflate(parent.context.inflater)
)
GENRE_SONG_ITEM_TYPE -> GenreSongViewHolder(
ItemGenreSongBinding.inflate(LayoutInflater.from(parent.context)),
ItemGenreSongBinding.inflate(parent.context.inflater),
)
else -> error("Bad viewholder item type $viewType")
@ -108,7 +108,7 @@ class GenreDetailAdapter(
inner class GenreHeaderViewHolder(
private val binding: ItemGenreHeaderBinding
) : BaseViewHolder<Genre>(binding, null, null) {
) : BaseHolder<Genre>(binding) {
override fun onBind(data: Genre) {
binding.genre = data
binding.detailModel = detailModel
@ -126,7 +126,7 @@ class GenreDetailAdapter(
inner class GenreSongViewHolder(
private val binding: ItemGenreSongBinding,
) : BaseViewHolder<Song>(binding, doOnClick, doOnLongClick), Highlightable {
) : BaseHolder<Song>(binding, doOnClick, doOnLongClick), Highlightable {
private val normalTextColor = binding.songName.currentTextColor
override fun onBind(data: Song) {

View file

@ -17,7 +17,7 @@ import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.BaseHolder
import org.oxycblt.auxio.recycler.viewholders.HeaderViewHolder
/**
@ -133,7 +133,7 @@ class QueueAdapter(
*/
inner class QueueSongViewHolder(
private val binding: ItemQueueSongBinding,
) : BaseViewHolder<Song>(binding, null, null) {
) : BaseHolder<Song>(binding) {
@SuppressLint("ClickableViewAccessibility")
override fun onBind(data: Song) {
@ -159,9 +159,8 @@ class QueueAdapter(
* ViewHolder for the **user queue header**. Has the clear queue button.
*/
inner class UserQueueHeaderViewHolder(
context: Context,
private val binding: ItemActionHeaderBinding
) : BaseViewHolder<Header>(binding, null, null) {
context: Context, private val binding: ItemActionHeaderBinding
) : BaseHolder<Header>(binding) {
init {
binding.headerButton.contentDescription = context.getString(

View file

@ -213,9 +213,6 @@ class PlaybackStateManager private constructor() {
mQueue = parent.songs.toMutableList()
mMode = PlaybackMode.IN_GENRE
}
else -> {
}
}
resetLoopMode()

View file

@ -8,19 +8,19 @@ import org.oxycblt.auxio.music.BaseModel
/**
* A [RecyclerView.ViewHolder] that streamlines a lot of the common things across all viewholders.
* @param T The datatype, inheriting [BaseModel] for this ViewHolder.
* @param baseBinding Basic [ViewDataBinding] required to set up click listeners & sizing.
* @param doOnClick Function that specifies what to do when an item is clicked. Specify null if you want no action to occur.
* @param doOnLongClick Function that specifies what to do when an item is long clicked. Specify null if you want no action to occur.
* @param binding Basic [ViewDataBinding] required to set up click listeners & sizing.
* @param doOnClick (Optional, defaults to null) Function that specifies what to do on a click. Null if nothing should be done.
* @param doOnLongClick (Optional, defaults to null) Functions that specifics what to do on a long click. Null if nothing should be done.
* @author OxygenCobalt
*/
abstract class BaseViewHolder<T : BaseModel>(
private val baseBinding: ViewDataBinding,
private val doOnClick: ((data: T) -> Unit)?,
private val doOnLongClick: ((view: View, data: T) -> Unit)?
) : RecyclerView.ViewHolder(baseBinding.root) {
abstract class BaseHolder<T : BaseModel>(
private val binding: ViewDataBinding,
private val doOnClick: ((data: T) -> Unit)? = null,
private val doOnLongClick: ((view: View, data: T) -> Unit)? = null
) : RecyclerView.ViewHolder(binding.root) {
init {
// Force the layout to *actually* be the screen width
baseBinding.root.layoutParams = RecyclerView.LayoutParams(
binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
)
}
@ -32,14 +32,14 @@ abstract class BaseViewHolder<T : BaseModel>(
*/
fun bind(data: T) {
doOnClick?.let { onClick ->
baseBinding.root.setOnClickListener {
binding.root.setOnClickListener {
onClick(data)
}
}
doOnLongClick?.let { onLongClick ->
baseBinding.root.setOnLongClickListener {
onLongClick(baseBinding.root, data)
binding.root.setOnLongClickListener {
onLongClick(binding.root, data)
true
}
@ -47,12 +47,12 @@ abstract class BaseViewHolder<T : BaseModel>(
onBind(data)
baseBinding.executePendingBindings()
binding.executePendingBindings()
}
/**
* Function that performs binding operations unique to the inheriting viewholder.
* Add any specialized code to an override of this instead of [BaseViewHolder] itself.
* Add any specialized code to an override of this instead of [BaseHolder] itself.
*/
protected abstract fun onBind(data: T)
}

View file

@ -38,7 +38,7 @@ class SongViewHolder private constructor(
private val binding: ItemSongBinding,
doOnClick: (data: Song) -> Unit,
doOnLongClick: (view: View, data: Song) -> Unit
) : BaseViewHolder<Song>(binding, doOnClick, doOnLongClick) {
) : BaseHolder<Song>(binding, doOnClick, doOnLongClick) {
override fun onBind(data: Song) {
binding.song = data
@ -73,7 +73,7 @@ class AlbumViewHolder private constructor(
private val binding: ItemAlbumBinding,
doOnClick: (data: Album) -> Unit,
doOnLongClick: (view: View, data: Album) -> Unit
) : BaseViewHolder<Album>(binding, doOnClick, doOnLongClick) {
) : BaseHolder<Album>(binding, doOnClick, doOnLongClick) {
override fun onBind(data: Album) {
binding.album = data
@ -106,7 +106,7 @@ class ArtistViewHolder private constructor(
private val binding: ItemArtistBinding,
doOnClick: (Artist) -> Unit,
doOnLongClick: (view: View, data: Artist) -> Unit
) : BaseViewHolder<Artist>(binding, doOnClick, doOnLongClick) {
) : BaseHolder<Artist>(binding, doOnClick, doOnLongClick) {
override fun onBind(data: Artist) {
binding.artist = data
@ -139,7 +139,7 @@ class GenreViewHolder private constructor(
private val binding: ItemGenreBinding,
doOnClick: (Genre) -> Unit,
doOnLongClick: (view: View, data: Genre) -> Unit
) : BaseViewHolder<Genre>(binding, doOnClick, doOnLongClick) {
) : BaseHolder<Genre>(binding, doOnClick, doOnLongClick) {
override fun onBind(data: Genre) {
binding.genre = data
@ -168,9 +168,7 @@ class GenreViewHolder private constructor(
/**
* The Shared ViewHolder for a [Header]. Instantiation should be done with [from]
*/
class HeaderViewHolder(
private val binding: ItemHeaderBinding
) : BaseViewHolder<Header>(binding, null, null) {
class HeaderViewHolder(private val binding: ItemHeaderBinding) : BaseHolder<Header>(binding) {
override fun onBind(data: Header) {
binding.header = data

View file

@ -9,6 +9,7 @@ import android.graphics.Point
import android.os.Build
import android.text.Spanned
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageButton
@ -72,6 +73,12 @@ fun Context.getPlural(@PluralsRes pluralsRes: Int, value: Int): String {
return resources.getQuantityString(pluralsRes, value, value)
}
/**
* Shortcut to get a [LayoutInflater] from a [Context]
*/
val Context.inflater: LayoutInflater get() = LayoutInflater.from(this)
/**
* Create a [Toast] from a [String]
* @param context [Context] required to create the toast