From f7e25d3fa89cd8b12ad1306525345f0fcc690e54 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Wed, 9 Sep 2020 19:01:28 -0600 Subject: [PATCH] Add navigation to LibraryFragment Add navigiation to LibraryFragment. This navigation is nested so that one can still move through the ViewPager, which will certainly have no problems later on. /s --- .../auxio/detail/ArtistDetailFragment.kt | 37 +++++++++ .../oxycblt/auxio/library/LibraryFragment.kt | 53 ++++++++---- .../auxio/library/LibraryListFragment.kt | 49 +++++++++++ .../auxio/library/adapters/AlbumAdapter.kt | 4 +- .../auxio/library/adapters/ArtistAdapter.kt | 4 +- .../org/oxycblt/auxio/music/MusicViewModel.kt | 2 +- .../org/oxycblt/auxio/music/models/Artist.kt | 2 +- .../recycler/viewholders/AlbumViewHolder.kt | 4 +- .../recycler/viewholders/ArtistViewHolder.kt | 4 +- .../recycler/viewholders/SongViewHolder.kt | 4 +- .../org/oxycblt/auxio/songs/SongAdapter.kt | 4 +- app/src/main/res/layout/activity_main.xml | 3 +- .../res/layout/fragment_artist_detail.xml | 21 +++++ app/src/main/res/layout/fragment_library.xml | 15 ++-- .../main/res/layout/fragment_library_list.xml | 18 +++++ app/src/main/res/layout/fragment_loading.xml | 3 +- app/src/main/res/layout/fragment_songs.xml | 3 +- app/src/main/res/layout/item_album.xml | 62 ++++++++++++++ app/src/main/res/layout/item_artist.xml | 63 +++++++++++++++ app/src/main/res/layout/item_song.xml | 81 +++++++++++++++++++ app/src/main/res/navigation/nav_library.xml | 26 ++++++ 21 files changed, 419 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt create mode 100644 app/src/main/java/org/oxycblt/auxio/library/LibraryListFragment.kt create mode 100644 app/src/main/res/layout/fragment_artist_detail.xml create mode 100644 app/src/main/res/layout/fragment_library_list.xml create mode 100644 app/src/main/res/layout/item_album.xml create mode 100644 app/src/main/res/layout/item_artist.xml create mode 100644 app/src/main/res/layout/item_song.xml create mode 100644 app/src/main/res/navigation/nav_library.xml diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt new file mode 100644 index 000000000..fb37ed077 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -0,0 +1,37 @@ +package org.oxycblt.auxio.detail + +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 org.oxycblt.auxio.R +import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding +import org.oxycblt.auxio.music.MusicViewModel + +class ArtistDetailFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val binding = DataBindingUtil.inflate( + inflater, R.layout.fragment_artist_detail, container, false + ) + + // I honestly don't want to turn of the any data classes into a parcelables due to how + // many lists they store, so just pick up the artist id and find it from musicModel. + val musicModel: MusicViewModel by activityViewModels() + val artistId = ArtistDetailFragmentArgs.fromBundle(requireArguments()).artistId + + binding.artist = musicModel.artists.value?.find { it.id == artistId } + + Log.d(this::class.simpleName, "Fragment created.") + + return binding.root + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt index 5be07c565..4d7d2b8b9 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt @@ -5,21 +5,17 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels +import androidx.navigation.NavController +import androidx.navigation.fragment.NavHostFragment import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentLibraryBinding -import org.oxycblt.auxio.library.adapters.ArtistAdapter -import org.oxycblt.auxio.music.MusicViewModel -import org.oxycblt.auxio.recycler.ClickListener -import org.oxycblt.auxio.recycler.applyDivider class LibraryFragment : Fragment() { - private val musicModel: MusicViewModel by activityViewModels { - MusicViewModel.Factory(requireActivity().application) - } + private var navController: NavController? = null override fun onCreateView( inflater: LayoutInflater, @@ -30,17 +26,44 @@ class LibraryFragment : Fragment() { inflater, R.layout.fragment_library, container, false ) - binding.libraryRecycler.adapter = ArtistAdapter( - musicModel.artists.value!!, - ClickListener { artist -> - Log.d(this::class.simpleName, artist.name) - } + requireActivity().onBackPressedDispatcher.addCallback( + viewLifecycleOwner, callback ) - binding.libraryRecycler.applyDivider() - binding.libraryRecycler.setHasFixedSize(true) + + val navHost = childFragmentManager.findFragmentById(R.id.nav_host) as? NavHostFragment + navController = navHost?.navController Log.d(this::class.simpleName, "Fragment created.") return binding.root } + + override fun onResume() { + super.onResume() + + callback.isEnabled = true + } + + override fun onPause() { + super.onPause() + callback.isEnabled = false + } + + val callback = object : OnBackPressedCallback(false) { + + override fun handleOnBackPressed() { + + // If at the root of the navigation, perform onBackPressed from the main activity. + if (navController?.currentDestination?.id == navController?.graph?.startDestination) { + // Disable the callback as it will get caught in an infinite loop otherwise. + isEnabled = false + + requireActivity().onBackPressed() + + isEnabled = true + } else { + navController?.navigateUp() + } + } + } } diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryListFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryListFragment.kt new file mode 100644 index 000000000..7273c6b37 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryListFragment.kt @@ -0,0 +1,49 @@ +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.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.recycler.ClickListener +import org.oxycblt.auxio.recycler.applyDivider + +class LibraryListFragment : Fragment() { + + private val musicModel: MusicViewModel by activityViewModels { + MusicViewModel.Factory(requireActivity().application) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val binding = DataBindingUtil.inflate( + inflater, R.layout.fragment_library_list, container, false + ) + + binding.libraryRecycler.adapter = ArtistAdapter( + musicModel.artists.value!!, + ClickListener { artist -> + findNavController().navigate( + LibraryListFragmentDirections.actionShowArtist(artist.id) + ) + } + ) + binding.libraryRecycler.applyDivider() + binding.libraryRecycler.setHasFixedSize(true) + + Log.d(this::class.simpleName, "Fragment created.") + + return binding.root + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt index 8d458e909..2cce7de53 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/adapters/AlbumAdapter.kt @@ -3,7 +3,7 @@ package org.oxycblt.auxio.library.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.AlbumItemBinding +import org.oxycblt.auxio.databinding.ItemAlbumBinding import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder @@ -16,7 +16,7 @@ class AlbumAdapter( override fun getItemCount(): Int = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder { - val binding = AlbumItemBinding.inflate(LayoutInflater.from(parent.context)) + val binding = ItemAlbumBinding.inflate(LayoutInflater.from(parent.context)) // Force the item to *actually* be the screen width so ellipsizing can work. binding.root.layoutParams = RecyclerView.LayoutParams( diff --git a/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt b/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt index 9578ec849..96a2a23d8 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/adapters/ArtistAdapter.kt @@ -3,7 +3,7 @@ package org.oxycblt.auxio.library.adapters import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.ArtistItemBinding +import org.oxycblt.auxio.databinding.ItemArtistBinding import org.oxycblt.auxio.music.models.Artist import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder @@ -16,7 +16,7 @@ class ArtistAdapter( override fun getItemCount(): Int = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArtistViewHolder { - val binding = ArtistItemBinding.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. binding.root.layoutParams = RecyclerView.LayoutParams( diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt index 6eb284b9c..c2bc68537 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt @@ -20,7 +20,7 @@ import org.oxycblt.auxio.music.processing.MusicLoader import org.oxycblt.auxio.music.processing.MusicLoaderResponse import org.oxycblt.auxio.music.processing.MusicSorter -// Storage for music data. +// ViewModel for music storage. May also be a god object. class MusicViewModel(private val app: Application) : ViewModel() { // Coroutine diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt index 9c120a239..fb8c3a6a6 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt @@ -1,6 +1,6 @@ package org.oxycblt.auxio.music.models -// Abstraction for mAlbums +// Abstraction for albums data class Artist( val id: Long = 0, var name: String = "", diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/AlbumViewHolder.kt b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/AlbumViewHolder.kt index 02c333b4b..b42eed3ce 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/AlbumViewHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/AlbumViewHolder.kt @@ -1,12 +1,12 @@ package org.oxycblt.auxio.recycler.viewholders import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.AlbumItemBinding +import org.oxycblt.auxio.databinding.ItemAlbumBinding import org.oxycblt.auxio.music.models.Album // Generic ViewHolder for an album class AlbumViewHolder( - private val binding: AlbumItemBinding + private val binding: ItemAlbumBinding ) : RecyclerView.ViewHolder(binding.root) { // Bind the view w/new data diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt index f64dbdbc5..5fed6488a 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt @@ -1,12 +1,12 @@ package org.oxycblt.auxio.recycler.viewholders import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.ArtistItemBinding +import org.oxycblt.auxio.databinding.ItemArtistBinding import org.oxycblt.auxio.music.models.Artist // Generic ViewHolder for an album class ArtistViewHolder( - private val binding: ArtistItemBinding + private val binding: ItemArtistBinding ) : RecyclerView.ViewHolder(binding.root) { // Bind the view w/new data diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/SongViewHolder.kt b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/SongViewHolder.kt index 3de59aaec..d459818de 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/SongViewHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/SongViewHolder.kt @@ -1,12 +1,12 @@ package org.oxycblt.auxio.recycler.viewholders import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.SongItemBinding +import org.oxycblt.auxio.databinding.ItemSongBinding import org.oxycblt.auxio.music.models.Song // Generic ViewHolder for a song class SongViewHolder( - private val binding: SongItemBinding + private val binding: ItemSongBinding ) : RecyclerView.ViewHolder(binding.root) { // Bind the view w/new data diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt index 2b13bebd6..3b11143ba 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/SongAdapter.kt @@ -3,7 +3,7 @@ package org.oxycblt.auxio.songs import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.databinding.SongItemBinding +import org.oxycblt.auxio.databinding.ItemSongBinding import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.viewholders.SongViewHolder @@ -16,7 +16,7 @@ class SongAdapter( override fun getItemCount(): Int = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder { - val binding = SongItemBinding.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. binding.root.layoutParams = RecyclerView.LayoutParams( diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 175c4e2ce..b7a2822e9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -12,8 +12,7 @@ + android:layout_height="match_parent"> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index a98600dcf..0981c4ef1 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -1,12 +1,11 @@ - - - + app:defaultNavHost="false" + app:navGraph="@navigation/nav_library" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_library_list.xml b/app/src/main/res/layout/fragment_library_list.xml new file mode 100644 index 000000000..0f897bd67 --- /dev/null +++ b/app/src/main/res/layout/fragment_library_list.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_loading.xml b/app/src/main/res/layout/fragment_loading.xml index aba183510..83c3430d8 100644 --- a/app/src/main/res/layout/fragment_loading.xml +++ b/app/src/main/res/layout/fragment_loading.xml @@ -14,8 +14,7 @@ + android:layout_height="match_parent"> + tools:listitem="@layout/item_song" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_album.xml b/app/src/main/res/layout/item_album.xml new file mode 100644 index 000000000..4d9a2035c --- /dev/null +++ b/app/src/main/res/layout/item_album.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_artist.xml b/app/src/main/res/layout/item_artist.xml new file mode 100644 index 000000000..d18160d91 --- /dev/null +++ b/app/src/main/res/layout/item_artist.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_song.xml b/app/src/main/res/layout/item_song.xml new file mode 100644 index 000000000..c4eb1bdc2 --- /dev/null +++ b/app/src/main/res/layout/item_song.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_library.xml b/app/src/main/res/navigation/nav_library.xml new file mode 100644 index 000000000..453f48fae --- /dev/null +++ b/app/src/main/res/navigation/nav_library.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file