Heavily refactor navigation
Make how navigation to the detail fragments much simpler/easier to maintain compared to previously.
This commit is contained in:
parent
fafaa0bf1f
commit
60af5f8656
15 changed files with 143 additions and 120 deletions
|
@ -14,8 +14,6 @@ import androidx.navigation.fragment.NavHostFragment
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
|
@ -95,12 +93,10 @@ class MainFragment : Fragment() {
|
|||
if (it != null && navController != null) {
|
||||
val curDest = navController.currentDestination?.id
|
||||
|
||||
val isOk = when (it) {
|
||||
is Song -> (detailModel.currentAlbum.value?.id == it.album.id) magic (curDest != R.id.album_detail_fragment)
|
||||
is Album -> (detailModel.currentAlbum.value?.id == it.id) magic (curDest != R.id.album_detail_fragment)
|
||||
is Artist -> (detailModel.currentArtist.value?.id == it.id) magic (curDest != R.id.artist_detail_fragment)
|
||||
var isOk = false
|
||||
|
||||
else -> false
|
||||
if (curDest == R.id.songs_fragment || curDest == R.id.settings_fragment) {
|
||||
isOk = true
|
||||
}
|
||||
|
||||
if (isOk) {
|
||||
|
@ -116,17 +112,6 @@ class MainFragment : Fragment() {
|
|||
return binding.root
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic boolean logic that gets navigation working.
|
||||
* true true -> true |
|
||||
* true false -> false |
|
||||
* false true -> true |
|
||||
* false false -> false |
|
||||
*/
|
||||
private infix fun Boolean.magic(other: Boolean): Boolean {
|
||||
return if (!this && !other) false else !(this && !other)
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom navigator code that has proper animations, unlike BottomNavigationView.setupWithNavController().
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.oxycblt.auxio.R
|
|||
import org.oxycblt.auxio.detail.adapters.AlbumDetailAdapter
|
||||
import org.oxycblt.auxio.logD
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
|
@ -82,28 +83,41 @@ class AlbumDetailFragment : DetailFragment() {
|
|||
detailAdapter.submitList(data)
|
||||
}
|
||||
|
||||
detailModel.doneWithNavToParent()
|
||||
|
||||
detailModel.navToParent.observe(viewLifecycleOwner) {
|
||||
if (it) {
|
||||
findNavController().navigate(
|
||||
AlbumDetailFragmentDirections.actionShowParentArtist(
|
||||
detailModel.currentAlbum.value!!.artist.id
|
||||
)
|
||||
)
|
||||
|
||||
detailModel.doneWithNavToParent()
|
||||
}
|
||||
}
|
||||
|
||||
detailModel.navToItem.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
if (it is Song) {
|
||||
scrollToPlayingItem()
|
||||
}
|
||||
logD(it.name)
|
||||
when (it) {
|
||||
is Song -> {
|
||||
if (detailModel.currentAlbum.value!!.id == it.album.id) {
|
||||
scrollToItem(it.id)
|
||||
|
||||
if (it is Album && it.id == detailModel.currentAlbum.value!!.id) {
|
||||
detailModel.doneWithNavToItem()
|
||||
detailModel.doneWithNavToItem()
|
||||
} else {
|
||||
findNavController().navigate(
|
||||
AlbumDetailFragmentDirections.actionShowAlbum(it.album.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is Album -> {
|
||||
if (detailModel.currentAlbum.value!!.id == it.id) {
|
||||
binding.detailRecycler.scrollToPosition(0)
|
||||
detailModel.doneWithNavToItem()
|
||||
} else {
|
||||
findNavController().navigate(
|
||||
AlbumDetailFragmentDirections.actionShowAlbum(it.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is Artist -> {
|
||||
logD("Hello?")
|
||||
findNavController().navigate(
|
||||
AlbumDetailFragmentDirections.actionShowArtist(it.id)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,14 +158,11 @@ class AlbumDetailFragment : DetailFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to the currently playing item.
|
||||
*/
|
||||
private fun scrollToPlayingItem() {
|
||||
private fun scrollToItem(id: Long) {
|
||||
// Calculate where the item for the currently played song is
|
||||
val pos = detailModel.albumSortMode.value!!.getSortedSongList(
|
||||
detailModel.currentAlbum.value!!.songs
|
||||
).indexOf(playbackModel.song.value)
|
||||
).indexOfFirst { it.id == id }
|
||||
|
||||
if (pos != -1) {
|
||||
binding.detailRecycler.post {
|
||||
|
@ -167,8 +178,6 @@ class AlbumDetailFragment : DetailFragment() {
|
|||
binding.detailAppbar.isLifted = true
|
||||
}
|
||||
}
|
||||
|
||||
detailModel.doneWithNavToItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.oxycblt.auxio.music.Album
|
|||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
|
@ -77,8 +78,22 @@ class ArtistDetailFragment : DetailFragment() {
|
|||
}
|
||||
|
||||
detailModel.navToItem.observe(viewLifecycleOwner) {
|
||||
if (it != null && it is Artist) {
|
||||
detailModel.doneWithNavToItem()
|
||||
if (it != null) {
|
||||
if (it is Artist) {
|
||||
if (it.id == detailModel.currentArtist.value!!.id) {
|
||||
detailModel.doneWithNavToItem()
|
||||
} else {
|
||||
findNavController().navigate(
|
||||
ArtistDetailFragmentDirections.actionShowArtist(it.id)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val albumId = if (it is Song) it.album.id else it.id
|
||||
|
||||
findNavController().navigate(
|
||||
ArtistDetailFragmentDirections.actionShowAlbum(albumId)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import org.oxycblt.auxio.databinding.FragmentDetailBinding
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.fixAnimationInfoMemoryLeak
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.memberBinding
|
||||
|
||||
|
@ -44,6 +45,12 @@ abstract class DetailFragment : Fragment() {
|
|||
callback.isEnabled = false
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
||||
fixAnimationInfoMemoryLeak()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut method for doing setup of the detail toolbar.
|
||||
*/
|
||||
|
|
|
@ -36,16 +36,10 @@ class DetailViewModel : ViewModel() {
|
|||
private val mCurrentAlbum = MutableLiveData<Album?>()
|
||||
val currentAlbum: LiveData<Album?> get() = mCurrentAlbum
|
||||
|
||||
// Navigation flags
|
||||
// Primary navigation flag.
|
||||
private val mNavToItem = MutableLiveData<BaseModel?>()
|
||||
val navToItem: LiveData<BaseModel?> get() = mNavToItem
|
||||
|
||||
private val mNavToParent = MutableLiveData<Boolean>()
|
||||
val navToParent: LiveData<Boolean> get() = mNavToParent
|
||||
|
||||
private val mNavToChild = MutableLiveData<BaseModel?>()
|
||||
val navToChild: LiveData<BaseModel?> get() = mNavToChild
|
||||
|
||||
/**
|
||||
* Update the current navigation status
|
||||
* @param value Whether the current [DetailFragment] is navigating or not.
|
||||
|
@ -113,23 +107,4 @@ class DetailViewModel : ViewModel() {
|
|||
fun doneWithNavToItem() {
|
||||
mNavToItem.value = null
|
||||
}
|
||||
|
||||
/** Mark that parent navigation should occur */
|
||||
fun navToParent() {
|
||||
mNavToParent.value = true
|
||||
}
|
||||
|
||||
/** Mark that the UI is done with the parent navigation */
|
||||
fun doneWithNavToParent() {
|
||||
mNavToParent.value = false
|
||||
}
|
||||
|
||||
/** Navigate to some child item (Primarily used by GenreDetailFragment) */
|
||||
fun navToChild(child: BaseModel) {
|
||||
mNavToChild.value = child
|
||||
}
|
||||
|
||||
fun doneWithNavToChild() {
|
||||
mNavToChild.value = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.oxycblt.auxio.music.Album
|
|||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.music.MusicStore
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
|
@ -69,19 +70,23 @@ class GenreDetailFragment : DetailFragment() {
|
|||
detailAdapter.submitList(data)
|
||||
}
|
||||
|
||||
detailModel.navToChild.observe(viewLifecycleOwner) {
|
||||
detailModel.navToItem.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
if (it is Artist) {
|
||||
findNavController().navigate(
|
||||
GenreDetailFragmentDirections.actionGoArtist(it.id)
|
||||
when (it) {
|
||||
is Artist -> findNavController().navigate(
|
||||
GenreDetailFragmentDirections.actionShowArtist(it.id)
|
||||
)
|
||||
} else if (it is Album) {
|
||||
findNavController().navigate(
|
||||
GenreDetailFragmentDirections.actionGoAlbum(it.id)
|
||||
)
|
||||
}
|
||||
|
||||
detailModel.doneWithNavToChild()
|
||||
is Album -> findNavController().navigate(
|
||||
GenreDetailFragmentDirections.actionShowAlbum(it.id)
|
||||
)
|
||||
|
||||
is Song -> findNavController().navigate(
|
||||
GenreDetailFragmentDirections.actionShowAlbum(it.album.id)
|
||||
)
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.databinding.FragmentSearchBinding
|
||||
import org.oxycblt.auxio.detail.DetailViewModel
|
||||
import org.oxycblt.auxio.logD
|
||||
import org.oxycblt.auxio.logE
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.BaseModel
|
||||
|
@ -26,6 +26,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
import org.oxycblt.auxio.ui.ActionMenu
|
||||
import org.oxycblt.auxio.ui.accent
|
||||
import org.oxycblt.auxio.ui.fixAnimationInfoMemoryLeak
|
||||
import org.oxycblt.auxio.ui.getLandscapeSpans
|
||||
import org.oxycblt.auxio.ui.isLandscape
|
||||
import org.oxycblt.auxio.ui.requireCompatActivity
|
||||
|
@ -40,6 +41,7 @@ class SearchFragment : Fragment() {
|
|||
// SearchViewModel only scoped to this Fragment
|
||||
private val searchModel: SearchViewModel by viewModels()
|
||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||
private val detailModel: DetailViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -113,25 +115,27 @@ class SearchFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
detailModel.navToItem.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
findNavController().navigate(
|
||||
when (it) {
|
||||
is Song -> SearchFragmentDirections.actionShowAlbum(it.album.id)
|
||||
is Album -> SearchFragmentDirections.actionShowAlbum(it.id)
|
||||
is Artist -> SearchFragmentDirections.actionShowArtist(it.id)
|
||||
|
||||
else -> return@observe
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
||||
try {
|
||||
// Use reflection to fix a memory leak in the fragment source code that occurs
|
||||
// from leaving an EditText focused when exiting the view.
|
||||
// I cant believe I have to do this.
|
||||
Fragment::class.java.getDeclaredMethod("setFocusedView", View::class.java).apply {
|
||||
isAccessible = true
|
||||
invoke(this@SearchFragment, null)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logE("Hacky reflection leak fix failed.")
|
||||
|
||||
e.printStackTrace()
|
||||
}
|
||||
fixAnimationInfoMemoryLeak()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -137,13 +137,13 @@ class ActionMenu(
|
|||
|
||||
R.id.action_go_album -> {
|
||||
if (data is Song) {
|
||||
determineWhereToNavWithSong(data.album)
|
||||
detailModel.navToItem(data.album)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_go_artist -> {
|
||||
if (data is Song) {
|
||||
determineWhereToNavWithSong(data.album.artist)
|
||||
detailModel.navToItem(data.album.artist)
|
||||
} else if (data is Album) {
|
||||
detailModel.navToItem(data.artist)
|
||||
}
|
||||
|
@ -151,14 +151,6 @@ class ActionMenu(
|
|||
}
|
||||
}
|
||||
|
||||
private fun determineWhereToNavWithSong(parent: BaseModel) {
|
||||
when (flag) {
|
||||
FLAG_NONE -> detailModel.navToItem(parent)
|
||||
FLAG_IN_ALBUM -> detailModel.navToParent()
|
||||
FLAG_IN_GENRE -> detailModel.navToChild(parent)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** No Flags **/
|
||||
const val FLAG_NONE = -1
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.graphics.Point
|
|||
import android.os.Build
|
||||
import android.text.Spanned
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
|
@ -20,6 +21,7 @@ import androidx.core.text.HtmlCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.logE
|
||||
|
||||
// --- VIEW CONFIGURATION ---
|
||||
|
||||
|
@ -139,6 +141,7 @@ fun Activity.isIrregularLandscape(): Boolean {
|
|||
* Check if the system bars are on the bottom.
|
||||
* @return If the system bars are on the bottom, false if no.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
private fun isSystemBarOnBottom(activity: Activity): Boolean {
|
||||
val realPoint = Point()
|
||||
val metrics = DisplayMetrics()
|
||||
|
@ -170,3 +173,21 @@ private fun isSystemBarOnBottom(activity: Activity): Boolean {
|
|||
|
||||
return (!canMove || width < height)
|
||||
}
|
||||
|
||||
// --- HACKY NIGHTMARES ---
|
||||
|
||||
/**
|
||||
* Use R E F L E C T I O N to fix a memory leak where mAnimationInfo will keep a reference to
|
||||
* its focused view.
|
||||
* I can't believe I have to do this.
|
||||
*/
|
||||
fun Fragment.fixAnimationInfoMemoryLeak() {
|
||||
try {
|
||||
Fragment::class.java.getDeclaredMethod("setFocusedView", View::class.java).let {
|
||||
it.isAccessible = true
|
||||
it.invoke(this, null)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logE("mAnimationInfo leak fix failed.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
android:id="@+id/playback_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="@color/background"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
android:background="@drawable/ui_ripple"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:onClick="@{() -> detailModel.navToParent()}"
|
||||
android:onClick="@{() -> detailModel.navToItem(album.artist)}"
|
||||
android:text="@{album.artist.name}"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
android:id="@+id/playback_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="@color/background"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
android:id="@+id/playback_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="@color/background"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_medium"
|
||||
android:onClick="@{() -> detailModel.navToParent()}"
|
||||
android:onClick="@{() -> detailModel.navToItem(album.artist)}"
|
||||
android:text="@{album.artist.name}"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
|
|
|
@ -39,12 +39,18 @@
|
|||
<argument
|
||||
android:name="artistId"
|
||||
app:argType="long" />
|
||||
<action
|
||||
android:id="@+id/action_show_artist"
|
||||
app:destination="@id/artist_detail_fragment"
|
||||
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" />
|
||||
<action
|
||||
android:id="@+id/action_show_album"
|
||||
app:destination="@id/album_detail_fragment"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:launchSingleTop="true"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
</fragment>
|
||||
|
@ -57,12 +63,19 @@
|
|||
android:name="albumId"
|
||||
app:argType="long" />
|
||||
<action
|
||||
android:id="@+id/action_show_parent_artist"
|
||||
android:id="@+id/action_show_artist"
|
||||
app:destination="@id/artist_detail_fragment"
|
||||
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" />
|
||||
<action
|
||||
android:id="@+id/action_show_album"
|
||||
app:destination="@id/album_detail_fragment"
|
||||
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" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/genre_detail_fragment"
|
||||
|
@ -73,14 +86,14 @@
|
|||
android:name="genreId"
|
||||
app:argType="long" />
|
||||
<action
|
||||
android:id="@+id/action_go_artist"
|
||||
android:id="@+id/action_show_artist"
|
||||
app:destination="@id/artist_detail_fragment"
|
||||
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" />
|
||||
<action
|
||||
android:id="@+id/action_go_album"
|
||||
android:id="@+id/action_show_album"
|
||||
app:destination="@id/album_detail_fragment"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
|
@ -92,11 +105,6 @@
|
|||
android:name="org.oxycblt.auxio.songs.SongsFragment"
|
||||
android:label="fragment_songs"
|
||||
tools:layout="@layout/fragment_songs" />
|
||||
<fragment
|
||||
android:id="@+id/settings_fragment"
|
||||
android:name="org.oxycblt.auxio.settings.SettingsFragment"
|
||||
android:label="SettingsFragment"
|
||||
tools:layout="@layout/fragment_settings" />
|
||||
<fragment
|
||||
android:id="@+id/search_fragment"
|
||||
android:name="org.oxycblt.auxio.search.SearchFragment"
|
||||
|
@ -124,4 +132,9 @@
|
|||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/settings_fragment"
|
||||
android:name="org.oxycblt.auxio.settings.SettingsFragment"
|
||||
android:label="SettingsFragment"
|
||||
tools:layout="@layout/fragment_settings" />
|
||||
</navigation>
|
Loading…
Reference in a new issue