Add ellipsizing to song/album items

Add ellipsizing to the song and album items, also modify their inflation so that the items take up the entire screen width.
This commit is contained in:
OxygenCobalt 2020-08-31 07:51:14 -06:00
parent c8f7419833
commit dc45e2973a
11 changed files with 97 additions and 56 deletions

View file

@ -15,17 +15,10 @@ import org.oxycblt.auxio.songs.SongsFragment
class MainFragment : Fragment() { class MainFragment : Fragment() {
private val shownFragments = listOf( private val shownFragments = listOf(0, 1)
0, 1
)
private val libraryFragment: LibraryFragment by lazy { private val libraryFragment: LibraryFragment by lazy { LibraryFragment() }
LibraryFragment() private val songsFragment: SongsFragment by lazy { SongsFragment() }
}
private val songsFragment: SongsFragment by lazy {
SongsFragment()
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -44,9 +37,14 @@ class MainFragment : Fragment() {
return binding.root return binding.root
} }
private fun getFragment(pos: Int): Fragment { private inner class PagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
if (shownFragments.contains(pos)) { override fun getItemCount(): Int = shownFragments.size
return when (pos) {
override fun createFragment(position: Int): Fragment {
Log.d(this::class.simpleName, "Switching to fragment $position.")
if (shownFragments.contains(position)) {
return when (position) {
0 -> libraryFragment 0 -> libraryFragment
1 -> songsFragment 1 -> songsFragment
@ -57,18 +55,10 @@ class MainFragment : Fragment() {
// Not sure how this would happen but it might // Not sure how this would happen but it might
Log.e( Log.e(
this::class.simpleName, this::class.simpleName,
"Something went terribly wrong while swapping fragments, Substituting with libraryFragment." "Attempted to index a fragment that shouldn't be shown. Returning libraryFragment."
) )
return libraryFragment return libraryFragment
} }
private inner class PagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
override fun getItemCount(): Int = shownFragments.size
override fun createFragment(position: Int): Fragment {
Log.d(this::class.simpleName, "Switching to fragment $position.")
return getFragment(position)
}
} }
} }

View file

@ -11,7 +11,7 @@ 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
private val ID3_GENRES = arrayOf<String>( private val ID3_GENRES = arrayOf(
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz",
"Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno",
"Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno",

View file

@ -21,7 +21,7 @@ enum class MusicLoaderResponse {
// Class that loads music from the FileSystem. // Class that loads music from the FileSystem.
// FIXME: This thing probably has some memory leaks *somewhere* // FIXME: This thing probably has some memory leaks *somewhere*
class MusicLoader(private val app: Application) { class MusicLoader(app: Application) {
var genres = mutableListOf<Genre>() var genres = mutableListOf<Genre>()
var artists = mutableListOf<Artist>() var artists = mutableListOf<Artist>()
@ -34,7 +34,7 @@ class MusicLoader(private val app: Application) {
private var songCursor: Cursor? = null private var songCursor: Cursor? = null
val response: MusicLoaderResponse val response: MusicLoaderResponse
val resolver: ContentResolver = app.contentResolver private val resolver: ContentResolver = app.contentResolver
init { init {
response = findMusic() response = findMusic()
@ -82,7 +82,7 @@ class MusicLoader(private val app: Application) {
// If a genre is still in an old int-based format [Android formats it as "(INT)"], // If a genre is still in an old int-based format [Android formats it as "(INT)"],
// convert that to the corresponding ID3 genre. Really hope anyone doesn't have // convert that to the corresponding ID3 genre. Really hope anyone doesn't have
// a genre that contains parentheses. // a genre that contains parentheses.
if (name.contains(Regex("[()]"))) { if (name.contains(Regex("[0123456789)]"))) {
name = name.toNamedGenre() name = name.toNamedGenre()
} }

View file

@ -11,13 +11,35 @@ class AlbumAdapter(private val data: List<Album>) : RecyclerView.Adapter<AlbumVi
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size
/*
private var time = 0
private var inflationCount = 0
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder {
return AlbumViewHolder( // val then = System.currentTimeMillis()
AlbumItemBinding.inflate(
LayoutInflater.from(parent.context) val binding = AlbumItemBinding.inflate(LayoutInflater.from(parent.context))
// Force the item to *actually* be the screen width so ellipsizing can work.
binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
) )
/*
time += (System.currentTimeMillis() - then).toInt()
inflationCount++
if (inflationCount == 10) {
Log.d(
this::class.simpleName,
"Initial inflation took ${time}ms"
) )
} }
*/
return AlbumViewHolder(binding)
}
override fun onBindViewHolder(holder: AlbumViewHolder, position: Int) { override fun onBindViewHolder(holder: AlbumViewHolder, position: Int) {
val album = data[position] val album = data[position]

View file

@ -11,14 +11,33 @@ class SongAdapter(private val data: List<Song>) : RecyclerView.Adapter<SongViewH
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size
/*
private var time = 0
private var inflationCount = 0
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
val then = System.currentTimeMillis()
val binding = SongItemBinding.inflate(LayoutInflater.from(parent.context)) val binding = SongItemBinding.inflate(LayoutInflater.from(parent.context))
// Force the layout to be the width of the screen so that the cutoff can work properly. // Force the item to *actually* be the screen width so ellipsizing can work.
binding.root.layoutParams = RecyclerView.LayoutParams( binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
) )
/*
time += (System.currentTimeMillis() - then).toInt()
inflationCount++
if (inflationCount == 10) {
Log.d(
this::class.simpleName,
"Initial inflation took ${time}ms"
)
}
*/
return SongViewHolder(binding) return SongViewHolder(binding)
} }

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.AlbumItemBinding import org.oxycblt.auxio.databinding.AlbumItemBinding
import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Album
@ -14,12 +13,7 @@ class AlbumViewHolder(
fun bind(album: Album) { fun bind(album: Album) {
binding.album = album binding.album = album
// Load the album cover binding.albumName.requestLayout()
binding.cover.load(album.coverUri) {
crossfade(true)
placeholder(android.R.color.transparent)
error(android.R.color.transparent)
}
binding.executePendingBindings() binding.executePendingBindings()
} }

View file

@ -13,6 +13,9 @@ class SongViewHolder(
fun bind(song: Song) { fun bind(song: Song) {
binding.song = song binding.song = song
binding.songName.requestLayout()
binding.songInfo.requestLayout()
binding.executePendingBindings() binding.executePendingBindings()
} }
} }

View file

@ -17,25 +17,30 @@
<ImageView <ImageView
android:id="@+id/cover" android:id="@+id/cover"
android:layout_width="@dimen/cover_size_compact" android:layout_width="@dimen/cover_size_normal"
android:layout_height="@dimen/cover_size_compact" android:layout_height="@dimen/cover_size_normal"
android:contentDescription="@{@string/description_cover_art + album.title}" android:contentDescription="@{@string/description_cover_art + album.title}"
app:coverArt="@{album}"
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="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{album.title}"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:text="@{album.title}"
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintBottom_toTopOf="@+id/song_count"
app:layout_constraintEnd_toEndOf="parent"
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
@ -47,8 +52,8 @@
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" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View file

@ -9,6 +9,5 @@
android:id="@+id/viewPager" android:id="@+id/viewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>
</layout> </layout>

View file

@ -30,12 +30,17 @@
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:text="@{song.title}"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:ellipsize="end"
android:maxLines="1"
android:text="@{song.title}"
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_info"
app:layout_constraintEnd_toEndOf="parent"
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
@ -43,11 +48,15 @@
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:ellipsize="end"
android:maxLines="1"
android:text="@{@string/format_song_info(song.album.artist.name, song.album.title)}"
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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cover" app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toBottomOf="@+id/song_name"
tools:text="Artist / Album" /> tools:text="Artist / Album" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -7,8 +7,8 @@
<dimen name="margin_small">8dp</dimen> <dimen name="margin_small">8dp</dimen>
<dimen name="margin_medium">16dp</dimen> <dimen name="margin_medium">16dp</dimen>
<dimen name="cover_size">64dp</dimen>
<dimen name="cover_size_compact">44dp</dimen> <dimen name="cover_size_compact">44dp</dimen>
<dimen name="cover_size_normal">56dp</dimen>
<dimen name="elevation_normal">4dp</dimen> <dimen name="elevation_normal">4dp</dimen>
</resources> </resources>