Update ViewHolder structure
Make some minor improvements to the ViewHolder structure.
This commit is contained in:
parent
55ed55c5dc
commit
32fe24e001
12 changed files with 60 additions and 63 deletions
|
@ -61,7 +61,7 @@ dependencies {
|
||||||
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
def navigation_version = "2.3.0"
|
def navigation_version = "2.3.1"
|
||||||
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
|
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
|
||||||
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
|
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class DetailAlbumAdapter(
|
class DetailAlbumAdapter(
|
||||||
private val doOnClick: (Album) -> Unit
|
private val doOnClick: (data: Album) -> Unit
|
||||||
) : ListAdapter<Album, DetailAlbumAdapter.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<Album, DetailAlbumAdapter.ViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -27,8 +27,8 @@ class DetailAlbumAdapter(
|
||||||
private val binding: ItemArtistAlbumBinding,
|
private val binding: ItemArtistAlbumBinding,
|
||||||
) : BaseViewHolder<Album>(binding, doOnClick) {
|
) : BaseViewHolder<Album>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Album) {
|
override fun onBind(data: Album) {
|
||||||
binding.album = model
|
binding.album = data
|
||||||
|
|
||||||
binding.albumName.requestLayout()
|
binding.albumName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
class DetailArtistAdapter(
|
class DetailArtistAdapter(
|
||||||
private val doOnClick: (Artist) -> Unit
|
private val doOnClick: (data: Artist) -> Unit
|
||||||
) : ListAdapter<Artist, DetailArtistAdapter.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<Artist, DetailArtistAdapter.ViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -27,8 +27,8 @@ class DetailArtistAdapter(
|
||||||
private val binding: ItemGenreArtistBinding
|
private val binding: ItemGenreArtistBinding
|
||||||
) : BaseViewHolder<Artist>(binding, doOnClick) {
|
) : BaseViewHolder<Artist>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Artist) {
|
override fun onBind(data: Artist) {
|
||||||
binding.artist = model
|
binding.artist = data
|
||||||
|
|
||||||
binding.artistName.requestLayout()
|
binding.artistName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,24 +2,18 @@ package org.oxycblt.auxio.detail.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.ColorInt
|
|
||||||
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.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
import org.oxycblt.auxio.theme.accent
|
|
||||||
import org.oxycblt.auxio.theme.toColor
|
|
||||||
|
|
||||||
class DetailSongAdapter(
|
class DetailSongAdapter(
|
||||||
private val doOnClick: (Song) -> Unit
|
private val doOnClick: (data: Song) -> Unit
|
||||||
) : ListAdapter<Song, DetailSongAdapter.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<Song, DetailSongAdapter.ViewHolder>(DiffCallback()) {
|
||||||
private var currentSong: Song? = null
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(
|
return ViewHolder(
|
||||||
ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context)),
|
ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context))
|
||||||
accent.first.toColor(parent.context)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,15 +24,10 @@ class DetailSongAdapter(
|
||||||
// Generic ViewHolder for a song
|
// Generic ViewHolder for a song
|
||||||
inner class ViewHolder(
|
inner class ViewHolder(
|
||||||
private val binding: ItemAlbumSongBinding,
|
private val binding: ItemAlbumSongBinding,
|
||||||
@ColorInt private val resolvedAccent: Int
|
|
||||||
) : BaseViewHolder<Song>(binding, doOnClick) {
|
) : BaseViewHolder<Song>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Song) {
|
override fun onBind(data: Song) {
|
||||||
binding.song = model
|
binding.song = data
|
||||||
|
|
||||||
if (model == currentSong) {
|
|
||||||
binding.songName.setTextColor(resolvedAccent)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.songName.requestLayout()
|
binding.songName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
|
||||||
// It cannot display multiple ViewHolders *at once* however. That's what SearchAdapter is for.
|
// It cannot display multiple ViewHolders *at once* however. That's what SearchAdapter is for.
|
||||||
class LibraryAdapter(
|
class LibraryAdapter(
|
||||||
private val showMode: ShowMode,
|
private val showMode: ShowMode,
|
||||||
private val doOnClick: (BaseModel) -> Unit
|
private val doOnClick: (data: BaseModel) -> Unit
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
private var data: List<BaseModel>
|
private var data: List<BaseModel>
|
||||||
|
|
|
@ -17,7 +17,7 @@ import org.oxycblt.auxio.recycler.viewholders.HeaderViewHolder
|
||||||
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
private val doOnClick: (BaseModel) -> Unit
|
private val doOnClick: (data: BaseModel) -> Unit
|
||||||
) : ListAdapter<BaseModel, RecyclerView.ViewHolder>(DiffCallback<BaseModel>()) {
|
) : ListAdapter<BaseModel, RecyclerView.ViewHolder>(DiffCallback<BaseModel>()) {
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import org.oxycblt.auxio.music.toDuration
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.Random.Default.nextLong
|
import kotlin.random.Random.Default.nextLong
|
||||||
|
|
||||||
// TODO: Editing/Adding to Queue
|
// TODO: Adding to Queue
|
||||||
// TODO: Add the playback service itself
|
// TODO: Add the playback service itself
|
||||||
// TODO: Add loop control [From playback]
|
// TODO: Add loop control [From playback]
|
||||||
// TODO: Implement persistence through Bundles [I want to keep my shuffles, okay?]
|
// TODO: Implement persistence through Bundles [I want to keep my shuffles, okay?]
|
||||||
|
|
|
@ -28,8 +28,12 @@ class QueueAdapter(
|
||||||
) : BaseViewHolder<Song>(binding, null) {
|
) : BaseViewHolder<Song>(binding, null) {
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onBind(model: Song) {
|
override fun onBind(data: Song) {
|
||||||
binding.song = model
|
binding.song = data
|
||||||
|
|
||||||
|
binding.songName.requestLayout()
|
||||||
|
binding.songInfo.requestLayout()
|
||||||
|
|
||||||
binding.songDragHandle.setOnTouchListener { _, motionEvent ->
|
binding.songDragHandle.setOnTouchListener { _, motionEvent ->
|
||||||
binding.songDragHandle.performClick()
|
binding.songDragHandle.performClick()
|
||||||
|
|
||||||
|
@ -40,9 +44,6 @@ class QueueAdapter(
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.songName.requestLayout()
|
|
||||||
binding.songInfo.requestLayout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.oxycblt.auxio.music.BaseModel
|
||||||
// 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.
|
||||||
abstract class BaseViewHolder<T : BaseModel>(
|
abstract class BaseViewHolder<T : BaseModel>(
|
||||||
private val baseBinding: ViewDataBinding,
|
private val baseBinding: ViewDataBinding,
|
||||||
private val doOnClick: ((T) -> Unit)?
|
private val doOnClick: ((data: T) -> Unit)?
|
||||||
) : RecyclerView.ViewHolder(baseBinding.root) {
|
) : RecyclerView.ViewHolder(baseBinding.root) {
|
||||||
init {
|
init {
|
||||||
// Force the layout to *actually* be the screen width
|
// Force the layout to *actually* be the screen width
|
||||||
|
@ -16,15 +16,17 @@ abstract class BaseViewHolder<T : BaseModel>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(model: T) {
|
fun bind(data: T) {
|
||||||
doOnClick?.let {
|
doOnClick?.let { onClick ->
|
||||||
baseBinding.root.setOnClickListener { it(model) }
|
baseBinding.root.setOnClickListener {
|
||||||
|
onClick(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBind(model)
|
onBind(data)
|
||||||
|
|
||||||
baseBinding.executePendingBindings()
|
baseBinding.executePendingBindings()
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun onBind(model: T)
|
protected abstract fun onBind(data: T)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ import org.oxycblt.auxio.music.Song
|
||||||
// All new instances should be created with from() instead of direct instantiation.
|
// All new instances should be created with from() instead of direct instantiation.
|
||||||
|
|
||||||
class GenreViewHolder private constructor(
|
class GenreViewHolder private constructor(
|
||||||
doOnClick: (Genre) -> Unit,
|
private val binding: ItemGenreBinding,
|
||||||
private val binding: ItemGenreBinding
|
doOnClick: (Genre) -> Unit
|
||||||
) : BaseViewHolder<Genre>(binding, doOnClick) {
|
) : BaseViewHolder<Genre>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Genre) {
|
override fun onBind(data: Genre) {
|
||||||
binding.genre = model
|
binding.genre = data
|
||||||
binding.genreName.requestLayout()
|
binding.genreName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,20 +31,20 @@ class GenreViewHolder private constructor(
|
||||||
|
|
||||||
fun from(context: Context, doOnClick: (Genre) -> Unit): GenreViewHolder {
|
fun from(context: Context, doOnClick: (Genre) -> Unit): GenreViewHolder {
|
||||||
return GenreViewHolder(
|
return GenreViewHolder(
|
||||||
doOnClick,
|
ItemGenreBinding.inflate(LayoutInflater.from(context)),
|
||||||
ItemGenreBinding.inflate(LayoutInflater.from(context))
|
doOnClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArtistViewHolder private constructor(
|
class ArtistViewHolder private constructor(
|
||||||
|
private val binding: ItemArtistBinding,
|
||||||
doOnClick: (Artist) -> Unit,
|
doOnClick: (Artist) -> Unit,
|
||||||
private val binding: ItemArtistBinding
|
|
||||||
) : BaseViewHolder<Artist>(binding, doOnClick) {
|
) : BaseViewHolder<Artist>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Artist) {
|
override fun onBind(data: Artist) {
|
||||||
binding.artist = model
|
binding.artist = data
|
||||||
binding.artistName.requestLayout()
|
binding.artistName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,30 +53,30 @@ class ArtistViewHolder private constructor(
|
||||||
|
|
||||||
fun from(context: Context, doOnClick: (Artist) -> Unit): ArtistViewHolder {
|
fun from(context: Context, doOnClick: (Artist) -> Unit): ArtistViewHolder {
|
||||||
return ArtistViewHolder(
|
return ArtistViewHolder(
|
||||||
doOnClick,
|
ItemArtistBinding.inflate(LayoutInflater.from(context)),
|
||||||
ItemArtistBinding.inflate(LayoutInflater.from(context))
|
doOnClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AlbumViewHolder private constructor(
|
class AlbumViewHolder private constructor(
|
||||||
doOnClick: (Album) -> Unit,
|
private val binding: ItemAlbumBinding,
|
||||||
private val binding: ItemAlbumBinding
|
doOnClick: (data: Album) -> Unit
|
||||||
) : BaseViewHolder<Album>(binding, doOnClick) {
|
) : BaseViewHolder<Album>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Album) {
|
override fun onBind(data: Album) {
|
||||||
binding.album = model
|
binding.album = data
|
||||||
binding.albumName.requestLayout()
|
binding.albumName.requestLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ITEM_TYPE = 12
|
const val ITEM_TYPE = 12
|
||||||
|
|
||||||
fun from(context: Context, doOnClick: (Album) -> Unit): AlbumViewHolder {
|
fun from(context: Context, doOnClick: (data: Album) -> Unit): AlbumViewHolder {
|
||||||
return AlbumViewHolder(
|
return AlbumViewHolder(
|
||||||
|
ItemAlbumBinding.inflate(LayoutInflater.from(context)),
|
||||||
doOnClick,
|
doOnClick,
|
||||||
ItemAlbumBinding.inflate(LayoutInflater.from(context))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,12 +85,12 @@ class AlbumViewHolder private constructor(
|
||||||
// TODO: Add indicators to song recycler items when they're being played?
|
// TODO: Add indicators to song recycler items when they're being played?
|
||||||
|
|
||||||
class SongViewHolder private constructor(
|
class SongViewHolder private constructor(
|
||||||
doOnClick: (Song) -> Unit,
|
private val binding: ItemSongBinding,
|
||||||
private val binding: ItemSongBinding
|
doOnClick: (data: Song) -> Unit,
|
||||||
) : BaseViewHolder<Song>(binding, doOnClick) {
|
) : BaseViewHolder<Song>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Song) {
|
override fun onBind(data: Song) {
|
||||||
binding.song = model
|
binding.song = data
|
||||||
|
|
||||||
binding.songName.requestLayout()
|
binding.songName.requestLayout()
|
||||||
binding.songInfo.requestLayout()
|
binding.songInfo.requestLayout()
|
||||||
|
@ -99,10 +99,13 @@ class SongViewHolder private constructor(
|
||||||
companion object {
|
companion object {
|
||||||
const val ITEM_TYPE = 13
|
const val ITEM_TYPE = 13
|
||||||
|
|
||||||
fun from(context: Context, doOnClick: (Song) -> Unit): SongViewHolder {
|
fun from(
|
||||||
|
context: Context,
|
||||||
|
doOnClick: (data: Song) -> Unit,
|
||||||
|
): SongViewHolder {
|
||||||
return SongViewHolder(
|
return SongViewHolder(
|
||||||
doOnClick,
|
ItemSongBinding.inflate(LayoutInflater.from(context)),
|
||||||
ItemSongBinding.inflate(LayoutInflater.from(context))
|
doOnClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,8 +114,9 @@ class SongViewHolder private constructor(
|
||||||
class HeaderViewHolder(
|
class HeaderViewHolder(
|
||||||
private val binding: ItemHeaderBinding
|
private val binding: ItemHeaderBinding
|
||||||
) : BaseViewHolder<Header>(binding, null) {
|
) : BaseViewHolder<Header>(binding, null) {
|
||||||
override fun onBind(model: Header) {
|
|
||||||
binding.header = model
|
override fun onBind(data: Header) {
|
||||||
|
binding.header = data
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
|
||||||
|
|
||||||
class SongAdapter(
|
class SongAdapter(
|
||||||
private val data: List<Song>,
|
private val data: List<Song>,
|
||||||
private val doOnClick: (Song) -> Unit
|
private val doOnClick: (data: Song) -> Unit
|
||||||
) : RecyclerView.Adapter<SongViewHolder>() {
|
) : RecyclerView.Adapter<SongViewHolder>() {
|
||||||
|
|
||||||
override fun getItemCount(): Int = data.size
|
override fun getItemCount(): Int = data.size
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
<string name="label_shuffle">Shuffle</string>
|
<string name="label_shuffle">Shuffle</string>
|
||||||
<string name="label_play">Play</string>
|
<string name="label_play">Play</string>
|
||||||
<string name="label_queue">Queue</string>
|
<string name="label_queue">Queue</string>
|
||||||
|
<string name="label_queue_add">Add to queue</string>
|
||||||
|
|
||||||
<!-- Hint Namespace | EditText Hints -->
|
<!-- Hint Namespace | EditText Hints -->
|
||||||
<string name="hint_search_library">Search Library…</string>
|
<string name="hint_search_library">Search Library…</string>
|
||||||
|
|
Loading…
Reference in a new issue