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:
parent
c8f7419833
commit
dc45e2973a
11 changed files with 97 additions and 56 deletions
|
@ -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,31 +37,28 @@ class MainFragment : Fragment() {
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFragment(pos: Int): Fragment {
|
|
||||||
if (shownFragments.contains(pos)) {
|
|
||||||
return when (pos) {
|
|
||||||
0 -> libraryFragment
|
|
||||||
1 -> songsFragment
|
|
||||||
|
|
||||||
else -> libraryFragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not sure how this would happen but it might
|
|
||||||
Log.e(
|
|
||||||
this::class.simpleName,
|
|
||||||
"Something went terribly wrong while swapping fragments, Substituting with libraryFragment."
|
|
||||||
)
|
|
||||||
|
|
||||||
return libraryFragment
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class PagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
private inner class PagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||||
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.")
|
Log.d(this::class.simpleName, "Switching to fragment $position.")
|
||||||
return getFragment(position)
|
|
||||||
|
if (shownFragments.contains(position)) {
|
||||||
|
return when (position) {
|
||||||
|
0 -> libraryFragment
|
||||||
|
1 -> songsFragment
|
||||||
|
|
||||||
|
else -> libraryFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not sure how this would happen but it might
|
||||||
|
Log.e(
|
||||||
|
this::class.simpleName,
|
||||||
|
"Attempted to index a fragment that shouldn't be shown. Returning libraryFragment."
|
||||||
|
)
|
||||||
|
|
||||||
|
return libraryFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,34 @@ 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) {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue