Update RecyclerView item layouts

Update the song/album items to have the cover art be loaded by a BindingAdapter, and remove unnecessary chains.
This commit is contained in:
OxygenCobalt 2020-08-29 09:03:19 -06:00
parent 53710ca3f0
commit c8f7419833
12 changed files with 50 additions and 56 deletions

View file

@ -46,7 +46,7 @@ dependencies {
// Kotlin // Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// Support // --- SUPPORT ---
implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
@ -56,21 +56,15 @@ dependencies {
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"
// Lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
// Viewpager // Viewpager
implementation 'androidx.viewpager2:viewpager2:1.0.0' implementation 'androidx.viewpager2:viewpager2:1.0.0'
// --- THIRD PARTY ---
// Image loading // Image loading
implementation("io.coil-kt:coil:0.12.0") implementation 'io.coil-kt:coil:0.12.0'
/*
// Room Database
def room_version = "2.2.5"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-runtime:$room_version"
*/
// Lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
// Lint // Lint
ktlint "com.pinterest:ktlint:0.37.2" ktlint "com.pinterest:ktlint:0.37.2"

View file

@ -3,7 +3,6 @@ package org.oxycblt.auxio
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -11,7 +10,7 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) // AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
Log.d(this::class.simpleName, "Activity Created.") Log.d(this::class.simpleName, "Activity Created.")
} }

View file

@ -47,8 +47,8 @@ class MainFragment : Fragment() {
private fun getFragment(pos: Int): Fragment { private fun getFragment(pos: Int): Fragment {
if (shownFragments.contains(pos)) { if (shownFragments.contains(pos)) {
return when (pos) { return when (pos) {
1 -> libraryFragment 0 -> libraryFragment
0 -> songsFragment 1 -> songsFragment
else -> libraryFragment else -> libraryFragment
} }
@ -67,6 +67,7 @@ class MainFragment : Fragment() {
override fun getItemCount(): Int = shownFragments.size override fun getItemCount(): Int = shownFragments.size
override fun createFragment(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
Log.d(this::class.simpleName, "Switching to fragment $position.")
return getFragment(position) return getFragment(position)
} }
} }

View file

@ -10,7 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentLibraryBinding import org.oxycblt.auxio.databinding.FragmentLibraryBinding
import org.oxycblt.auxio.recycler.adapters.AlbumDataAdapter import org.oxycblt.auxio.recycler.adapters.AlbumAdapter
import org.oxycblt.auxio.recycler.applyDivider import org.oxycblt.auxio.recycler.applyDivider
class LibraryFragment : Fragment() { class LibraryFragment : Fragment() {
@ -28,7 +28,7 @@ class LibraryFragment : Fragment() {
inflater, R.layout.fragment_library, container, false inflater, R.layout.fragment_library, container, false
) )
val adapter = AlbumDataAdapter(libraryModel.albums.value!!) val adapter = AlbumAdapter(libraryModel.albums.value!!)
binding.libraryRecycler.adapter = adapter binding.libraryRecycler.adapter = adapter
binding.libraryRecycler.applyDivider() binding.libraryRecycler.applyDivider()

View file

@ -3,8 +3,10 @@ package org.oxycblt.auxio.music
import android.content.ContentUris import android.content.ContentUris
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.databinding.BindingAdapter import androidx.databinding.BindingAdapter
import coil.load
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Album
import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.music.models.Song
@ -62,6 +64,25 @@ fun Long.toAlbumArtURI(): Uri {
) )
} }
// Get the cover art
@BindingAdapter("coverArt")
fun ImageView.getCoverArt(any: Any) {
val uri = when (any) {
is Song -> any.album.coverUri
is Album -> any.coverUri
// TODO: Artist images
else -> Uri.EMPTY
}
load(uri) {
crossfade(true)
placeholder(android.R.color.transparent)
error(android.R.color.transparent)
}
}
// Format the amount of songs in an album // Format the amount of songs in an album
@BindingAdapter("songCount") @BindingAdapter("songCount")
fun TextView.getAlbumSongs(album: Album) { fun TextView.getAlbumSongs(album: Album) {
@ -71,13 +92,3 @@ fun TextView.getAlbumSongs(album: Album) {
context.getString(R.string.format_multi_song_count, album.numSongs.toString()) context.getString(R.string.format_multi_song_count, album.numSongs.toString())
} }
} }
// Format the artist/album data for a song
@BindingAdapter("songData")
fun TextView.getSongData(song: Song) {
text = context.getString(
R.string.format_song_data,
song.album.artist.name,
song.album.title
)
}

View file

@ -7,13 +7,15 @@ import org.oxycblt.auxio.databinding.AlbumItemBinding
import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Album
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
class AlbumDataAdapter(val data: List<Album>) : RecyclerView.Adapter<AlbumViewHolder>() { class AlbumAdapter(private val data: List<Album>) : RecyclerView.Adapter<AlbumViewHolder>() {
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder {
return AlbumViewHolder( return AlbumViewHolder(
AlbumItemBinding.inflate(LayoutInflater.from(parent.context)) AlbumItemBinding.inflate(
LayoutInflater.from(parent.context)
)
) )
} }

View file

@ -7,7 +7,7 @@ import org.oxycblt.auxio.databinding.SongItemBinding
import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.music.models.Song
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
class SongDataAdapter(val data: List<Song>) : RecyclerView.Adapter<SongViewHolder>() { class SongAdapter(private val data: List<Song>) : RecyclerView.Adapter<SongViewHolder>() {
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size

View file

@ -1,7 +1,6 @@
package org.oxycblt.auxio.recycler.viewholders package org.oxycblt.auxio.recycler.viewholders
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load
import org.oxycblt.auxio.databinding.SongItemBinding import org.oxycblt.auxio.databinding.SongItemBinding
import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.music.models.Song
@ -14,13 +13,6 @@ class SongViewHolder(
fun bind(song: Song) { fun bind(song: Song) {
binding.song = song binding.song = song
// Load the album cover
binding.cover.load(song.album.coverUri) {
crossfade(true)
placeholder(android.R.color.transparent)
error(android.R.color.transparent)
}
binding.executePendingBindings() binding.executePendingBindings()
} }
} }

View file

@ -10,7 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentSongsBinding import org.oxycblt.auxio.databinding.FragmentSongsBinding
import org.oxycblt.auxio.recycler.adapters.SongDataAdapter import org.oxycblt.auxio.recycler.adapters.SongAdapter
import org.oxycblt.auxio.recycler.applyDivider import org.oxycblt.auxio.recycler.applyDivider
class SongsFragment : Fragment() { class SongsFragment : Fragment() {
@ -28,8 +28,7 @@ class SongsFragment : Fragment() {
inflater, R.layout.fragment_songs, container, false inflater, R.layout.fragment_songs, container, false
) )
val adapter = SongDataAdapter(songsModel.songs.value!!) binding.songRecycler.adapter = SongAdapter(songsModel.songs.value!!)
binding.songRecycler.adapter = adapter
binding.songRecycler.applyDivider() binding.songRecycler.applyDivider()
binding.songRecycler.setHasFixedSize(true) binding.songRecycler.setHasFixedSize(true)

View file

@ -23,20 +23,19 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:coverArt="@{album}"
tools:src="@tools:sample/backgrounds/scenic" /> tools:src="@tools:sample/backgrounds/scenic" />
<TextView <TextView
android:id="@+id/album_name" android:id="@+id/album_name"
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:text="@{album.title}" android:text="@{album.title}"
android:layout_marginStart="@dimen/margin_medium"
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/song_count"
app:layout_constraintStart_toEndOf="@+id/cover" app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Album Name" /> tools:text="Album Name" />
<TextView <TextView
@ -48,7 +47,6 @@
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/cover" app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toBottomOf="@+id/album_name"
app:songCount="@{album}" app:songCount="@{album}"
tools:text="10 Songs" /> tools:text="10 Songs" />

View file

@ -20,6 +20,7 @@
android:layout_width="@dimen/cover_size_compact" android:layout_width="@dimen/cover_size_compact"
android:layout_height="@dimen/cover_size_compact" android:layout_height="@dimen/cover_size_compact"
android:contentDescription="@{@string/description_cover_art + song.album.title}" android:contentDescription="@{@string/description_cover_art + song.album.title}"
app:coverArt="@{song}"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -29,27 +30,24 @@
android:id="@+id/song_name" android:id="@+id/song_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:text="@{song.title}" android:text="@{song.title}"
android:layout_marginStart="@dimen/margin_medium"
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/song_data"
app:layout_constraintStart_toEndOf="@+id/cover" app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Song Name" /> tools:text="Song Name" />
<TextView <TextView
android:id="@+id/song_data" android:id="@+id/song_info"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:text="@{@string/format_song_info(song.album.title, song.album.artist.name)}"
android:textAppearance="?android:attr/textAppearanceListItemSecondary" android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/cover" app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toBottomOf="@+id/song_name"
app:songData="@{song}"
tools:text="Artist / Album" /> tools:text="Artist / Album" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -2,6 +2,9 @@
<resources> <resources>
<string name="app_name">Auxio</string> <string name="app_name">Auxio</string>
<string name="title_library_fragment">Library</string>
<string name="title_all_songs">All Songs</string>
<string name="error_no_music">No music found.</string> <string name="error_no_music">No music found.</string>
<string name="error_music_load_failed">Music loading failed.</string> <string name="error_music_load_failed">Music loading failed.</string>
@ -9,10 +12,7 @@
<string name="label_single_song">1 Song</string> <string name="label_single_song">1 Song</string>
<string name="format_multi_song_count">%s Songs</string> <string name="format_multi_song_count">%s Songs</string>
<string name="format_song_data">%s / %s</string> <string name="format_song_info">%s / %s</string>
<string name="title_library_fragment">Library</string>
<string name="title_all_songs">All Songs</string>
<string name="description_cover_art">Cover art for </string> <string name="description_cover_art">Cover art for </string>
</resources> </resources>