Switch from ViewPager to BottomNavigationView
Use BottomNavigationView as the main navigator of Auxio instead of a ViewPager + BottomNavigationView, primarily to fix some memory leaks and give Auxio a better UI design overall.
This commit is contained in:
parent
212ffbf2c7
commit
c3a61e6071
14 changed files with 206 additions and 106 deletions
|
@ -73,10 +73,9 @@ dependencies {
|
||||||
implementation 'androidx.media:media:1.2.0'
|
implementation 'androidx.media:media:1.2.0'
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
def room_version = '2.2.5'
|
def room_version = '2.3.0-alpha03'
|
||||||
implementation "androidx.room:room-runtime:$room_version"
|
implementation "androidx.room:room-runtime:$room_version"
|
||||||
kapt "androidx.room:room-compiler:$room_version"
|
kapt "androidx.room:room-compiler:$room_version"
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
|
||||||
implementation "androidx.room:room-ktx:$room_version"
|
implementation "androidx.room:room-ktx:$room_version"
|
||||||
|
|
||||||
// --- THIRD PARTY ---
|
// --- THIRD PARTY ---
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
package org.oxycblt.auxio
|
package org.oxycblt.auxio
|
||||||
|
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
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.core.content.ContextCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.google.android.material.tabs.TabLayout
|
|
||||||
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.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.songs.SongsFragment
|
|
||||||
import org.oxycblt.auxio.ui.accent
|
import org.oxycblt.auxio.ui.accent
|
||||||
import org.oxycblt.auxio.ui.getInactiveAlpha
|
import org.oxycblt.auxio.ui.getInactiveAlpha
|
||||||
import org.oxycblt.auxio.ui.getTransparentAccent
|
import org.oxycblt.auxio.ui.getTransparentAccent
|
||||||
|
@ -52,40 +50,24 @@ class MainFragment : Fragment() {
|
||||||
accent.first,
|
accent.first,
|
||||||
getInactiveAlpha(accent.first)
|
getInactiveAlpha(accent.first)
|
||||||
)
|
)
|
||||||
|
val navIconTints = ColorStateList(
|
||||||
|
arrayOf(
|
||||||
|
intArrayOf(-android.R.attr.state_checked),
|
||||||
|
intArrayOf(android.R.attr.state_checked)
|
||||||
|
),
|
||||||
|
intArrayOf(colorInactive, colorActive)
|
||||||
|
)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
// TODO: Add nested viewpager navigation [If practical]
|
|
||||||
|
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
binding.mainViewPager.adapter = PagerAdapter()
|
|
||||||
|
|
||||||
// Link the ViewPager & Tab View
|
binding.navBar.itemIconTintList = navIconTints
|
||||||
TabLayoutMediator(binding.mainTabs, binding.mainViewPager) { tab, position ->
|
binding.navBar.itemTextColor = navIconTints
|
||||||
tab.icon = ContextCompat.getDrawable(requireContext(), tabIcons[position])
|
((childFragmentManager.findFragmentById(R.id.explore_nav_host) as NavHostFragment?))?.let {
|
||||||
|
// TODO: Add animation with BottomNavigationView navs
|
||||||
// Set the icon tint to deselected if its not the default tab
|
binding.navBar.setupWithNavController(it.findNavController())
|
||||||
if (position > 0) {
|
}
|
||||||
tab.icon?.setTint(colorInactive)
|
|
||||||
}
|
|
||||||
}.attach()
|
|
||||||
|
|
||||||
// Set up the selected/deselected colors
|
|
||||||
binding.mainTabs.addOnTabSelectedListener(
|
|
||||||
object : TabLayout.OnTabSelectedListener {
|
|
||||||
|
|
||||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
|
||||||
tab.icon?.setTint(colorActive)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTabUnselected(tab: TabLayout.Tab) {
|
|
||||||
tab.icon?.setTint(colorInactive)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTabReselected(tab: TabLayout.Tab?) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
|
||||||
|
@ -107,35 +89,4 @@ class MainFragment : Fragment() {
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fragmentAt(position: Int): Fragment {
|
|
||||||
return when (position) {
|
|
||||||
0 -> LibraryFragment()
|
|
||||||
1 -> SongsFragment()
|
|
||||||
|
|
||||||
else -> SongsFragment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class PagerAdapter :
|
|
||||||
FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
|
|
||||||
override fun getItemCount(): Int = shownFragments.size
|
|
||||||
|
|
||||||
override fun createFragment(position: Int): Fragment {
|
|
||||||
Log.d(this::class.simpleName, "Switching to fragment $position.")
|
|
||||||
|
|
||||||
if (shownFragments.contains(position)) {
|
|
||||||
return fragmentAt(position)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a fragment that shouldn't be shown is somehow shown anyway, just return
|
|
||||||
// its intended fragment.
|
|
||||||
Log.e(
|
|
||||||
this::class.simpleName,
|
|
||||||
"Attempted to index a fragment that shouldn't be shown."
|
|
||||||
)
|
|
||||||
|
|
||||||
return fragmentAt(position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
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
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
@ -20,7 +19,7 @@ import org.oxycblt.auxio.ui.applyDivider
|
||||||
import org.oxycblt.auxio.ui.disable
|
import org.oxycblt.auxio.ui.disable
|
||||||
import org.oxycblt.auxio.ui.setupAlbumSongActions
|
import org.oxycblt.auxio.ui.setupAlbumSongActions
|
||||||
|
|
||||||
class AlbumDetailFragment : Fragment() {
|
class AlbumDetailFragment : DetailFragment() {
|
||||||
|
|
||||||
private val args: AlbumDetailFragmentArgs by navArgs()
|
private val args: AlbumDetailFragmentArgs by navArgs()
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
|
@ -5,7 +5,6 @@ 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.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
@ -17,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.applyDivider
|
import org.oxycblt.auxio.ui.applyDivider
|
||||||
import org.oxycblt.auxio.ui.disable
|
import org.oxycblt.auxio.ui.disable
|
||||||
|
|
||||||
class ArtistDetailFragment : Fragment() {
|
class ArtistDetailFragment : DetailFragment() {
|
||||||
private val args: ArtistDetailFragmentArgs by navArgs()
|
private val args: ArtistDetailFragmentArgs by navArgs()
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
|
@ -107,10 +106,4 @@ class ArtistDetailFragment : Fragment() {
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
|
|
||||||
detailModel.updateNavigationStatus(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
44
app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
Normal file
44
app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package org.oxycblt.auxio.detail
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Base [Fragment] implementing a [OnBackPressedCallback] so that Auxio will navigate upwards
|
||||||
|
* instead of out of the app if a Detail Fragment is currently open.
|
||||||
|
* @author OxygenCobalt
|
||||||
|
*/
|
||||||
|
abstract class DetailFragment : Fragment() {
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
callback.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
callback.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val callback = object : OnBackPressedCallback(false) {
|
||||||
|
|
||||||
|
override fun handleOnBackPressed() {
|
||||||
|
val navController = findNavController()
|
||||||
|
// Check if it's the root of nested fragments in this navhost
|
||||||
|
if (navController.currentDestination?.id == navController.graph.startDestination) {
|
||||||
|
isEnabled = false
|
||||||
|
requireActivity().onBackPressed()
|
||||||
|
isEnabled = true
|
||||||
|
} else {
|
||||||
|
navController.navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ 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.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
@ -17,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.applyDivider
|
import org.oxycblt.auxio.ui.applyDivider
|
||||||
import org.oxycblt.auxio.ui.disable
|
import org.oxycblt.auxio.ui.disable
|
||||||
|
|
||||||
class GenreDetailFragment : Fragment() {
|
class GenreDetailFragment : DetailFragment() {
|
||||||
|
|
||||||
private val args: GenreDetailFragmentArgs by navArgs()
|
private val args: GenreDetailFragmentArgs by navArgs()
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
|
@ -203,9 +203,9 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
when (baseModel) {
|
when (baseModel) {
|
||||||
is Genre -> MainFragmentDirections.actionShowGenre(baseModel.id)
|
is Genre -> LibraryFragmentDirections.actionShowGenre(baseModel.id)
|
||||||
is Artist -> MainFragmentDirections.actionShowArtist(baseModel.id)
|
is Artist -> LibraryFragmentDirections.actionShowArtist(baseModel.id)
|
||||||
is Album -> MainFragmentDirections.actionShowAlbum(baseModel.id, true)
|
is Album -> LibraryFragmentDirections.actionShowAlbum(baseModel.id, true)
|
||||||
|
|
||||||
// If given model wasn't valid, then reset the navigation status
|
// If given model wasn't valid, then reset the navigation status
|
||||||
// and abort the navigation.
|
// and abort the navigation.
|
||||||
|
|
|
@ -53,7 +53,11 @@ class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouc
|
||||||
viewHolder: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
target: RecyclerView.ViewHolder
|
target: RecyclerView.ViewHolder
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return playbackModel.moveQueueItems(viewHolder.adapterPosition, target.adapterPosition, queueAdapter)
|
return playbackModel.moveQueueItems(
|
||||||
|
viewHolder.adapterPosition,
|
||||||
|
target.adapterPosition,
|
||||||
|
queueAdapter
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||||
|
|
|
@ -539,7 +539,10 @@ class PlaybackStateManager private constructor() {
|
||||||
// If the parent was somehow dropped during saving, attempt to restore it.
|
// If the parent was somehow dropped during saving, attempt to restore it.
|
||||||
mSong?.let {
|
mSong?.let {
|
||||||
if (mParent == null && mMode != PlaybackMode.ALL_SONGS) {
|
if (mParent == null && mMode != PlaybackMode.ALL_SONGS) {
|
||||||
Log.d(this::class.simpleName, "Parent was corrupted while in mode $mMode. Attempting to restore.")
|
Log.d(
|
||||||
|
this::class.simpleName,
|
||||||
|
"Parent was corrupted while in mode $mMode. Attempting to restore."
|
||||||
|
)
|
||||||
mParent = when (mMode) {
|
mParent = when (mMode) {
|
||||||
PlaybackMode.IN_ARTIST -> it.album.artist
|
PlaybackMode.IN_ARTIST -> it.album.artist
|
||||||
PlaybackMode.IN_ALBUM -> it.album
|
PlaybackMode.IN_ALBUM -> it.album
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
type="org.oxycblt.auxio.playback.PlaybackViewModel" />
|
type="org.oxycblt.auxio.playback.PlaybackViewModel" />
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
<!-- TODO: Fix elevation not showing -->
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:background="@drawable/ui_ripple"
|
android:background="@drawable/ui_ripple"
|
||||||
|
|
|
@ -4,43 +4,46 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".MainFragment">
|
tools:context=".MainFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/main_layout"
|
android:id="@+id/main_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/main_view_pager"
|
android:id="@+id/explore_nav_host"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1" />
|
android:elevation="@dimen/elevation_normal"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/compact_playback"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:navGraph="@navigation/nav_explore"
|
||||||
|
tools:layout="@layout/fragment_library" />
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/compact_playback"
|
android:id="@+id/compact_playback"
|
||||||
|
android:name="org.oxycblt.auxio.playback.CompactPlaybackFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:name="org.oxycblt.auxio.playback.CompactPlaybackFragment"
|
app:layout_constraintBottom_toTopOf="@+id/nav_bar"
|
||||||
android:elevation="@dimen/elevation_normal" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:layout="@layout/fragment_compact_playback" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
android:id="@+id/main_tabs"
|
android:id="@+id/nav_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/height_tab_menu"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:background="@color/background"
|
||||||
android:background="?android:attr/windowBackground"
|
|
||||||
android:elevation="@dimen/elevation_normal"
|
android:elevation="@dimen/elevation_normal"
|
||||||
|
app:itemRippleColor="@color/selection_color"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:tabGravity="fill"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:tabIconTint="?attr/colorPrimary"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:tabIconTintMode="src_in"
|
app:menu="@menu/menu_nav" />
|
||||||
app:tabIndicator="@drawable/ui_indicator"
|
|
||||||
app:tabIndicatorColor="?attr/colorPrimary"
|
|
||||||
app:tabMode="fixed"
|
|
||||||
app:tabRippleColor="@color/selection_color"
|
|
||||||
tools:background="@color/control_color" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
</layout>
|
|
@ -46,7 +46,7 @@
|
||||||
android:layout_margin="@dimen/margin_mid_large"
|
android:layout_margin="@dimen/margin_mid_large"
|
||||||
android:contentDescription="@{@string/description_album_cover(song.name)}"
|
android:contentDescription="@{@string/description_album_cover(song.name)}"
|
||||||
android:outlineProvider="bounds"
|
android:outlineProvider="bounds"
|
||||||
android:elevation="4dp"
|
android:elevation="2dp"
|
||||||
app:coverArt="@{song}"
|
app:coverArt="@{song}"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/playback_song"
|
app:layout_constraintBottom_toTopOf="@+id/playback_song"
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
|
11
app/src/main/res/menu/menu_nav.xml
Normal file
11
app/src/main/res/menu/menu_nav.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/library_fragment"
|
||||||
|
android:title="@string/title_library_fragment"
|
||||||
|
android:icon="@drawable/ic_library" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/songs_fragment"
|
||||||
|
android:title="@string/label_songs"
|
||||||
|
android:icon="@drawable/ic_song" />
|
||||||
|
</menu>
|
92
app/src/main/res/navigation/nav_explore.xml
Normal file
92
app/src/main/res/navigation/nav_explore.xml
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?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_explore"
|
||||||
|
app:startDestination="@id/library_fragment">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/library_fragment"
|
||||||
|
android:name="org.oxycblt.auxio.library.LibraryFragment"
|
||||||
|
android:label="fragment_library"
|
||||||
|
tools:layout="@layout/fragment_library">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_genre"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/genre_detail_fragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_artist"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/artist_detail_fragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_album"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/album_detail_fragment" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/artist_detail_fragment"
|
||||||
|
android:name="org.oxycblt.auxio.detail.ArtistDetailFragment"
|
||||||
|
android:label="ArtistDetailFragment"
|
||||||
|
tools:layout="@layout/fragment_artist_detail">
|
||||||
|
<argument
|
||||||
|
android:name="artistId"
|
||||||
|
app:argType="long" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_album"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/album_detail_fragment"
|
||||||
|
app:launchSingleTop="true" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/album_detail_fragment"
|
||||||
|
android:name="org.oxycblt.auxio.detail.AlbumDetailFragment"
|
||||||
|
android:label="AlbumDetailFragment"
|
||||||
|
tools:layout="@layout/fragment_album_detail">
|
||||||
|
<argument
|
||||||
|
android:name="albumId"
|
||||||
|
app:argType="long" />
|
||||||
|
<argument
|
||||||
|
android:name="enableParentNav"
|
||||||
|
app:argType="boolean" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_parent_artist"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/artist_detail_fragment" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/genre_detail_fragment"
|
||||||
|
android:name="org.oxycblt.auxio.detail.GenreDetailFragment"
|
||||||
|
android:label="GenreDetailFragment"
|
||||||
|
tools:layout="@layout/fragment_genre_detail">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_show_artist"
|
||||||
|
app:enterAnim="@anim/nav_default_enter_anim"
|
||||||
|
app:exitAnim="@anim/nav_default_exit_anim"
|
||||||
|
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||||
|
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||||
|
app:destination="@id/artist_detail_fragment" />
|
||||||
|
<argument
|
||||||
|
android:name="genreId"
|
||||||
|
app:argType="long" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/songs_fragment"
|
||||||
|
android:name="org.oxycblt.auxio.songs.SongsFragment"
|
||||||
|
android:label="fragment_songs"
|
||||||
|
tools:layout="@layout/fragment_songs" />
|
||||||
|
</navigation>
|
Loading…
Reference in a new issue