Remove generic recycler module

Remove the generic RecyclerView module and put its contents into other classes.
This commit is contained in:
OxygenCobalt 2020-09-11 10:44:41 -06:00
parent 02e803746b
commit 860033ac14
24 changed files with 137 additions and 484 deletions

View file

@ -25,3 +25,6 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
} }
} }
// I wish I knew somewhere else to put this
class ClickListener<T>(val onClick: (T) -> Unit)

View file

@ -1,26 +1,17 @@
package org.oxycblt.auxio package org.oxycblt.auxio
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import org.oxycblt.auxio.databinding.FragmentMainBinding import org.oxycblt.auxio.databinding.FragmentMainBinding
import org.oxycblt.auxio.library.LibraryFragment import org.oxycblt.auxio.library.LibraryFragment
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.processing.MusicLoaderResponse
import org.oxycblt.auxio.songs.SongsFragment import org.oxycblt.auxio.songs.SongsFragment
import org.oxycblt.auxio.theme.accent import org.oxycblt.auxio.theme.accent
import org.oxycblt.auxio.theme.getInactiveAlpha import org.oxycblt.auxio.theme.getInactiveAlpha
@ -100,7 +91,8 @@ class MainFragment : Fragment() {
} }
} }
private inner class PagerAdapter : FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) { private inner class PagerAdapter :
FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
override fun getItemCount(): Int = shownFragments.size override fun getItemCount(): Int = shownFragments.size
override fun createFragment(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
@ -119,4 +111,4 @@ class MainFragment : Fragment() {
return libraryFragment return libraryFragment
} }
} }
} }

View file

@ -5,10 +5,8 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding
import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel

View file

@ -5,20 +5,16 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.MainFragment import org.oxycblt.auxio.ClickListener
import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentLibraryBinding import org.oxycblt.auxio.databinding.FragmentLibraryBinding
import org.oxycblt.auxio.library.adapters.ArtistAdapter import org.oxycblt.auxio.library.adapters.ArtistAdapter
import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.models.Artist import org.oxycblt.auxio.music.models.Artist
import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.theme.applyDivider
import org.oxycblt.auxio.recycler.applyDivider
class LibraryFragment : Fragment() { class LibraryFragment : Fragment() {

View file

@ -1,66 +0,0 @@
package org.oxycblt.auxio.library
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentLibraryListBinding
import org.oxycblt.auxio.library.adapters.ArtistAdapter
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.models.Artist
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.recycler.applyDivider
class LibraryListFragment : Fragment() {
private val musicModel: MusicViewModel by activityViewModels()
private val libraryModel: LibraryViewModel by lazy {
ViewModelProvider(this).get(LibraryViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = DataBindingUtil.inflate<FragmentLibraryListBinding>(
inflater, R.layout.fragment_library_list, container, false
)
binding.libraryRecycler.adapter = ArtistAdapter(
musicModel.artists.value!!,
ClickListener { navToArtist(it) }
)
binding.libraryRecycler.applyDivider()
binding.libraryRecycler.setHasFixedSize(true)
Log.d(this::class.simpleName, "Fragment created.")
return binding.root
}
override fun onPause() {
super.onPause()
libraryModel.isAlreadyNavigating = false
}
private fun navToArtist(artist: Artist) {
// Don't navigate to a fragment multiple times if multiple items are accepted.
if (!libraryModel.isAlreadyNavigating) {
libraryModel.isAlreadyNavigating = true
findNavController().navigate(
LibraryListFragmentDirections.actionShowArtist(artist.id)
)
}
}
}

View file

@ -3,36 +3,52 @@ package org.oxycblt.auxio.library.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.ClickListener
import org.oxycblt.auxio.databinding.ItemAlbumBinding import org.oxycblt.auxio.databinding.ItemAlbumBinding
import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Album
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
class AlbumAdapter( class AlbumAdapter(
private val data: List<Album>, private val data: List<Album>,
private val listener: ClickListener<Album> private val listener: ClickListener<Album>
) : RecyclerView.Adapter<AlbumViewHolder>() { ) : RecyclerView.Adapter<AlbumAdapter.ViewHolder>() {
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): ViewHolder {
val binding = ItemAlbumBinding.inflate(LayoutInflater.from(parent.context)) return ViewHolder(
ItemAlbumBinding.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
) )
return AlbumViewHolder(binding)
} }
override fun onBindViewHolder(holder: AlbumViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val album = data[position] val album = data[position]
holder.itemView.setOnClickListener {
listener.onClick(album)
}
holder.bind(album) holder.bind(album)
} }
// Generic ViewHolder for an album
inner class ViewHolder(
private val binding: ItemAlbumBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
// Force the viewholder to *actually* be the screen width so ellipsizing can work.
binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
)
}
// Bind the view w/new data
fun bind(album: Album) {
binding.album = album
binding.root.setOnClickListener {
listener.onClick(album)
}
// Force-update the layout so ellipsizing works.
binding.albumName.requestLayout()
binding.executePendingBindings()
}
}
} }

View file

@ -3,19 +3,20 @@ package org.oxycblt.auxio.library.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.ClickListener
import org.oxycblt.auxio.databinding.ItemAlbumBinding
import org.oxycblt.auxio.databinding.ItemArtistBinding import org.oxycblt.auxio.databinding.ItemArtistBinding
import org.oxycblt.auxio.music.models.Album
import org.oxycblt.auxio.music.models.Artist import org.oxycblt.auxio.music.models.Artist
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
class ArtistAdapter( class ArtistAdapter(
private val data: List<Artist>, private val data: List<Artist>,
private val listener: ClickListener<Artist> private val listener: ClickListener<Artist>
) : RecyclerView.Adapter<ArtistViewHolder>() { ) : RecyclerView.Adapter<ArtistAdapter.ViewHolder>() {
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArtistViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemArtistBinding.inflate(LayoutInflater.from(parent.context)) val binding = ItemArtistBinding.inflate(LayoutInflater.from(parent.context))
// Force the item to *actually* be the screen width so ellipsizing can work. // Force the item to *actually* be the screen width so ellipsizing can work.
@ -23,16 +24,36 @@ class ArtistAdapter(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
) )
return ArtistViewHolder(binding) return ViewHolder(binding)
} }
override fun onBindViewHolder(holder: ArtistViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val artist = data[position] holder.bind(data[position])
}
holder.itemView.setOnClickListener { // Generic ViewHolder for an artist
listener.onClick(artist) inner class ViewHolder(
private val binding: ItemArtistBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
// Force the viewholder to *actually* be the screen width so ellipsizing can work.
binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
)
} }
holder.bind(artist) // Bind the view w/new data
fun bind(artist: Artist) {
binding.artist = artist
binding.root.setOnClickListener {
listener.onClick(artist)
}
// Force-update the layout so ellipsizing works.
binding.artistName.requestLayout()
binding.executePendingBindings()
}
} }
} }

View file

@ -3,6 +3,7 @@ package org.oxycblt.auxio.loading
import android.Manifest import android.Manifest
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.transition.TransitionInflater
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -10,7 +11,6 @@ import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
@ -88,10 +88,6 @@ class LoadingFragment : Fragment(R.layout.fragment_loading) {
return binding.root return binding.root
} }
override fun onDestroyView() {
super.onDestroyView()
}
// Check for two things: // Check for two things:
// - If Auxio needs to show the rationale for getting the READ_EXTERNAL_STORAGE permission. // - If Auxio needs to show the rationale for getting the READ_EXTERNAL_STORAGE permission.
// - If Auxio straight up doesn't have the READ_EXTERNAL_STORAGE permission. // - If Auxio straight up doesn't have the READ_EXTERNAL_STORAGE permission.
@ -107,11 +103,14 @@ class LoadingFragment : Fragment(R.layout.fragment_loading) {
binding.loadingBar.visibility = View.GONE binding.loadingBar.visibility = View.GONE
if (response == MusicLoaderResponse.DONE) { if (response == MusicLoaderResponse.DONE) {
exitTransition = TransitionInflater.from(requireContext()).inflateTransition(
R.transition.transition_to_main
)
findNavController().navigate( findNavController().navigate(
LoadingFragmentDirections.actionToMain() LoadingFragmentDirections.actionToMain()
) )
} } else {
else {
binding.let { binding -> binding.let { binding ->
binding.errorText.text = binding.errorText.text =
if (response == MusicLoaderResponse.NO_MUSIC) if (response == MusicLoaderResponse.NO_MUSIC)

View file

@ -1,26 +0,0 @@
package org.oxycblt.auxio.recycler
import android.graphics.drawable.ColorDrawable
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R
import org.oxycblt.auxio.theme.toColor
// Apply a custom vertical divider
fun RecyclerView.applyDivider() {
val div = DividerItemDecoration(
context,
DividerItemDecoration.VERTICAL
)
div.setDrawable(
ColorDrawable(
R.color.divider_color.toColor(context)
)
)
addItemDecoration(div)
}
// Generic ClickListener
class ClickListener<T>(val onClick: (T) -> Unit)

View file

@ -1,20 +0,0 @@
package org.oxycblt.auxio.recycler.viewholders
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemAlbumBinding
import org.oxycblt.auxio.music.models.Album
// Generic ViewHolder for an album
class AlbumViewHolder(
private val binding: ItemAlbumBinding
) : RecyclerView.ViewHolder(binding.root) {
// Bind the view w/new data
fun bind(album: Album) {
binding.album = album
binding.albumName.requestLayout()
binding.executePendingBindings()
}
}

View file

@ -1,20 +0,0 @@
package org.oxycblt.auxio.recycler.viewholders
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemArtistBinding
import org.oxycblt.auxio.music.models.Artist
// Generic ViewHolder for an album
class ArtistViewHolder(
private val binding: ItemArtistBinding
) : RecyclerView.ViewHolder(binding.root) {
// Bind the view w/new data
fun bind(artist: Artist) {
binding.artist = artist
binding.artistName.requestLayout()
binding.executePendingBindings()
}
}

View file

@ -1,21 +0,0 @@
package org.oxycblt.auxio.recycler.viewholders
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.models.Song
// Generic ViewHolder for a song
class SongViewHolder(
private val binding: ItemSongBinding
) : RecyclerView.ViewHolder(binding.root) {
// Bind the view w/new data
fun bind(song: Song) {
binding.song = song
binding.songName.requestLayout()
binding.songInfo.requestLayout()
binding.executePendingBindings()
}
}

View file

@ -3,19 +3,20 @@ package org.oxycblt.auxio.songs
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.ClickListener
import org.oxycblt.auxio.databinding.ItemAlbumBinding
import org.oxycblt.auxio.databinding.ItemSongBinding import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.models.Album
import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.music.models.Song
import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
class SongAdapter( class SongAdapter(
private val data: List<Song>, private val data: List<Song>,
private val listener: ClickListener<Song> private val listener: ClickListener<Song>
) : RecyclerView.Adapter<SongViewHolder>() { ) : RecyclerView.Adapter<SongAdapter.ViewHolder>() {
override fun getItemCount(): Int = data.size override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemSongBinding.inflate(LayoutInflater.from(parent.context)) val binding = ItemSongBinding.inflate(LayoutInflater.from(parent.context))
// Force the item to *actually* be the screen width so ellipsizing can work. // Force the item to *actually* be the screen width so ellipsizing can work.
@ -23,16 +24,38 @@ class SongAdapter(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
) )
return SongViewHolder(binding) return ViewHolder(binding)
} }
override fun onBindViewHolder(holder: SongViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val song = data[position] holder.bind(data[position])
}
holder.itemView.setOnClickListener { // Generic ViewHolder for an album
listener.onClick(song) inner class ViewHolder(
private val binding: ItemSongBinding
) : RecyclerView.ViewHolder(binding.root) {
init {
// Force the viewholder to *actually* be the screen width so ellipsizing can work.
binding.root.layoutParams = RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT
)
} }
holder.bind(song) // Bind the view w/new data
fun bind(song: Song) {
binding.song = song
binding.root.setOnClickListener {
listener.onClick(song)
}
// Force-update the layouts so ellipsizing works.
binding.songName.requestLayout()
binding.songInfo.requestLayout()
binding.executePendingBindings()
}
} }
} }

View file

@ -8,11 +8,11 @@ import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import org.oxycblt.auxio.ClickListener
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.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.theme.applyDivider
import org.oxycblt.auxio.recycler.applyDivider
class SongsFragment : Fragment() { class SongsFragment : Fragment() {

View file

@ -1,8 +1,11 @@
package org.oxycblt.auxio.theme package org.oxycblt.auxio.theme
import android.content.Context import android.content.Context
import android.graphics.drawable.ColorDrawable
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
// Pairs of the base accent and its theme // Pairs of the base accent and its theme
@ -49,3 +52,19 @@ fun Int.toColor(context: Context): Int {
ContextCompat.getColor(context, android.R.color.black) ContextCompat.getColor(context, android.R.color.black)
} }
} }
// Apply a custom vertical divider
fun RecyclerView.applyDivider() {
val div = DividerItemDecoration(
context,
DividerItemDecoration.VERTICAL
)
div.setDrawable(
ColorDrawable(
R.color.divider_color.toColor(context)
)
)
addItemDecoration(div)
}

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host"
android:id="@+id/nav_host"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"

View file

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="album"
type="org.oxycblt.auxio.music.models.Album" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ripple"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_medium">
<ImageView
android:id="@+id/cover"
android:layout_width="@dimen/cover_size_normal"
android:layout_height="@dimen/cover_size_normal"
app:coverArt="@{album}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/backgrounds/scenic"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/album_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:text="@{album.name}"
android:textAppearance="?android:attr/textAppearanceListItem"
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_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Album Name" />
<TextView
android:id="@+id/song_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toBottomOf="@+id/album_name"
app:songCount="@{album}"
tools:text="10 Songs" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="artist"
type="org.oxycblt.auxio.music.models.Artist" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ripple"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_medium">
<ImageView
android:id="@+id/artist_image"
android:layout_width="@dimen/cover_size_normal"
android:layout_height="@dimen/cover_size_normal"
app:artistImage="@{artist}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/backgrounds/scenic"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/artist_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@{artist.name}"
android:layout_marginStart="@dimen/margin_medium"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/album_song_count"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/artist_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Artist Name" />
<TextView
android:id="@+id/album_song_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:layout_marginStart="@dimen/margin_medium"
android:textColor="?android:attr/textColorSecondary"
app:artistCounts="@{artist}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/artist_image"
app:layout_constraintTop_toBottomOf="@+id/artist_name"
tools:text="2 Albums, 20 Songs" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -30,6 +30,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{artist.name}" /> android:text="@{artist.name}" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View file

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:animateLayoutChanges="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold"
app:title="@string/title_library_fragment"
tools:titleTextColor="@color/blue" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/library_recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_artist" />
</LinearLayout>
</layout>

View file

@ -13,7 +13,7 @@
android:id="@+id/view_pager" android:id="@+id/view_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"/> android:layout_weight="1" />
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/tabs" android:id="@+id/tabs"

View file

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="song"
type="org.oxycblt.auxio.music.models.Song" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ripple"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/padding_medium">
<ImageView
android:id="@+id/cover"
android:layout_width="@dimen/cover_size_compact"
android:layout_height="@dimen/cover_size_compact"
app:coverArt="@{song}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/backgrounds/scenic"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/song_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:ellipsize="end"
android:maxLines="1"
android:text="@{song.name}"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/song_info"
app:layout_constraintEnd_toStartOf="@+id/duration"
app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Song Name" />
<TextView
android:id="@+id/song_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:text="@{@string/format_song_info(song.album.artist.name, song.album.name)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/duration"
app:layout_constraintStart_toEndOf="@+id/cover"
app:layout_constraintTop_toBottomOf="@+id/song_name"
tools:text="Artist / Album" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{song.formattedDuration}"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorTertiary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="16:16" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_library"
app:startDestination="@id/libraryListFragment">
<fragment
android:id="@+id/libraryListFragment"
android:name="org.oxycblt.auxio.library.LibraryListFragment"
android:label="LibraryFragment"
tools:layout="@layout/fragment_library_list">
<action
android:id="@+id/action_show_artist"
app:destination="@id/artistDetailFragment" />
</fragment>
<fragment
android:id="@+id/artistDetailFragment"
android:name="org.oxycblt.auxio.detail.ArtistDetailFragment"
android:label="ArtistDetailFragment"
tools:layout="@layout/fragment_artist_detail">
<argument
android:name="artistId"
app:argType="long" />
</fragment>
</navigation>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"/>