ui: return to old nested nav

It just...started working again. Beats me why.

Start using it again, but with most of the changes in-tact. I like the
way it looks.
This commit is contained in:
Alexander Capehart 2023-07-22 12:09:44 -06:00
parent 84a90e0364
commit 4b49174ced
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 170 additions and 126 deletions

View file

@ -31,14 +31,18 @@ import androidx.fragment.app.activityViewModels
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import com.google.android.material.R as MR
import com.google.android.material.bottomsheet.BackportBottomSheetBehavior
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialFadeThrough
import dagger.hilt.android.AndroidEntryPoint
import kotlin.math.max
import kotlin.math.min
import org.oxycblt.auxio.databinding.FragmentMainBinding
import org.oxycblt.auxio.detail.DetailViewModel
import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.Outer
import org.oxycblt.auxio.list.ListViewModel
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
@ -53,6 +57,7 @@ import org.oxycblt.auxio.util.coordinatorLayoutBehavior
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.systemBarInsetsCompat
import org.oxycblt.auxio.util.unlikelyToBeNull
@ -66,9 +71,10 @@ class MainFragment :
ViewBindingFragment<FragmentMainBinding>(),
ViewTreeObserver.OnPreDrawListener,
NavController.OnDestinationChangedListener {
private val playbackModel: PlaybackViewModel by activityViewModels()
private val listModel: ListViewModel by activityViewModels()
private val detailModel: DetailViewModel by activityViewModels()
private val homeModel: HomeViewModel by activityViewModels()
private val listModel: ListViewModel by activityViewModels()
private val playbackModel: PlaybackViewModel by activityViewModels()
private var sheetBackCallback: SheetBackPressedCallback? = null
private var detailBackCallback: DetailBackPressedCallback? = null
private var selectionBackCallback: SelectionBackPressedCallback? = null
@ -77,6 +83,12 @@ class MainFragment :
private var elevationNormal = 0f
private var initialNavDestinationChange = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialFadeThrough()
exitTransition = MaterialFadeThrough()
}
override fun onCreateBinding(inflater: LayoutInflater) = FragmentMainBinding.inflate(inflater)
override fun onBindingCreated(binding: FragmentMainBinding, savedInstanceState: Bundle?) {
@ -152,6 +164,7 @@ class MainFragment :
// --- VIEWMODEL SETUP ---
collectImmediately(detailModel.editedPlaylist, detailBackCallback::invalidateEnabled)
collectImmediately(homeModel.showOuter.flow, ::handleShowOuter)
collectImmediately(listModel.selected, selectionBackCallback::invalidateEnabled)
collectImmediately(playbackModel.song, ::updateSong)
collectImmediately(playbackModel.openPanel.flow, ::handlePanel)
@ -292,6 +305,17 @@ class MainFragment :
listModel.dropSelection()
}
private fun handleShowOuter(outer: Outer?) {
val directions =
when (outer) {
is Outer.Settings -> MainFragmentDirections.preferences()
is Outer.About -> MainFragmentDirections.about()
null -> return
}
findNavController().navigateSafe(directions)
homeModel.showOuter.consume()
}
private fun updateSong(song: Song?) {
if (song != null) {
tryShowSheets()

View file

@ -38,7 +38,6 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis
import dagger.hilt.android.AndroidEntryPoint
import java.lang.reflect.Field
@ -102,10 +101,9 @@ class HomeFragment :
// Orientation change will wipe whatever transition we were using prior, which will
// result in no transition when the user navigates back. Make sure we re-initialize
// our transitions.
when (val id = savedInstanceState.getInt(KEY_LAST_TRANSITION_ID, -2)) {
-2 -> {}
-1 -> applyFadeTransition()
else -> applyAxisTransition(id)
val axis = savedInstanceState.getInt(KEY_LAST_TRANSITION_ID, -1)
if (axis > -1) {
applyAxisTransition(axis)
}
}
}
@ -183,9 +181,9 @@ class HomeFragment :
}
override fun onSaveInstanceState(outState: Bundle) {
when (val transition = enterTransition) {
is MaterialFadeThrough -> outState.putInt(KEY_LAST_TRANSITION_ID, -1)
is MaterialSharedAxis -> outState.putInt(KEY_LAST_TRANSITION_ID, transition.axis)
val transition = enterTransition
if (transition is MaterialSharedAxis) {
outState.putInt(KEY_LAST_TRANSITION_ID, transition.axis)
}
super.onSaveInstanceState(outState)
@ -224,14 +222,12 @@ class HomeFragment :
}
R.id.action_settings -> {
logD("Navigating to preferences")
applyFadeTransition()
findNavController().navigateSafe(HomeFragmentDirections.preferences())
homeModel.showSettings()
true
}
R.id.action_about -> {
logD("Navigating to about")
applyFadeTransition()
findNavController().navigateSafe(HomeFragmentDirections.about())
homeModel.showAbout()
true
}
@ -612,13 +608,6 @@ class HomeFragment :
reenterTransition = MaterialSharedAxis(axis, false)
}
private fun applyFadeTransition() {
enterTransition = MaterialFadeThrough()
returnTransition = MaterialFadeThrough()
exitTransition = MaterialFadeThrough()
reenterTransition = MaterialFadeThrough()
}
/**
* [FragmentStateAdapter] implementation for the [HomeFragment]'s [ViewPager2] instance.
*

View file

@ -131,6 +131,10 @@ constructor(
/** A marker for whether the user is fast-scrolling in the home view or not. */
val isFastScrolling: StateFlow<Boolean> = _isFastScrolling
private val _showOuter = MutableEvent<Outer>()
val showOuter: Event<Outer>
get() = _showOuter
init {
musicRepository.addUpdateListener(this)
homeSettings.registerListener(this)
@ -265,6 +269,14 @@ constructor(
_isFastScrolling.value = isFastScrolling
}
fun showSettings() {
_showOuter.put(Outer.Settings)
}
fun showAbout() {
_showOuter.put(Outer.About)
}
/**
* Create a list of [MusicType]s representing a simpler version of the [Tab] configuration.
*
@ -274,3 +286,8 @@ constructor(
private fun makeTabTypes() =
homeSettings.homeTabs.filterIsInstance<Tab.Visible>().map { it.type }
}
sealed interface Outer {
object Settings : Outer
object About : Outer
}

View file

@ -196,7 +196,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
}
override fun onRoundModeChanged() {
// TODO: Make this a recreate as soon as you can make the bottom sheet stop freaking out
cornerRadiusRes = getCornerRadiusRes()
applyBackgroundsToChildren()
val cover = currentCover ?: return

View file

@ -80,7 +80,7 @@ class SongMenuDialogFragment : MenuDialogFragment<Menu.ForSong>() {
requireContext().showToast(R.string.lng_queue_added)
}
R.id.action_artist_details -> detailModel.showArtist(menu.song)
R.id.action_album_details -> detailModel.showAlbum(menu.song)
R.id.action_album_details -> detailModel.showAlbum(menu.song.album)
R.id.action_share -> requireContext().share(menu.song)
R.id.action_playlist_add -> musicModel.addToPlaylist(menu.song)
R.id.action_detail -> detailModel.showSong(menu.song)

View file

@ -2,7 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@integer/m3_sys_motion_duration_medium4"
android:interpolator="@interpolator/m3_sys_motion_easing_emphasized">
<!-- Workaround for ugly default bottom sheet dialog transition -->
<!-- Replacement for ugly default bottom sheet dialog transition -->
<translate
android:fromYDelta="100%p"
android:toYDelta="0" />

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@integer/m3_sys_motion_duration_medium3"
android:interpolator="@interpolator/m3_sys_motion_easing_emphasized">
<!-- Workaround for ugly default bottom sheet dialog transition -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Replacement for ugly default bottom sheet dialog transition -->
<translate
android:duration="@integer/m3_sys_motion_duration_medium3"
android:fromYDelta="0"
android:interpolator="@interpolator/m3_sys_motion_easing_emphasized"
android:toYDelta="100%p" />
</set>

View file

@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentBehavior"
app:navGraph="@navigation/main"
app:navGraph="@navigation/inner"
app:defaultNavHost="true"
tools:layout="@layout/fragment_home" />

View file

@ -3,8 +3,10 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_host"
android:name="org.oxycblt.auxio.MainFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:defaultNavHost="true"
app:navGraph="@navigation/outer"
tools:layout="@layout/fragment_main" />

View file

@ -14,7 +14,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentBehavior"
app:navGraph="@navigation/main"
app:navGraph="@navigation/inner"
app:defaultNavHost="true"
tools:layout="@layout/fragment_home" />

View file

@ -12,12 +12,6 @@
<action
android:id="@+id/search"
app:destination="@id/search_fragment" />
<action
android:id="@+id/preferences"
app:destination="@id/root_preferences_fragment" />
<action
android:id="@+id/about"
app:destination="@id/about_fragment" />
<action
android:id="@+id/show_song"
app:destination="@id/song_detail_dialog" />
@ -394,93 +388,4 @@
android:name="parcel"
app:argType="org.oxycblt.auxio.list.Menu$ForPlaylist$Parcel" />
</dialog>
<fragment
android:id="@+id/root_preferences_fragment"
android:name="org.oxycblt.auxio.settings.RootPreferenceFragment"
android:label="fragment_settings">
<action
android:id="@+id/ui_preferences"
app:destination="@id/ui_preferences_fragment" />
<action
android:id="@+id/personalize_preferences"
app:destination="@id/personalize_preferences_fragment" />
<action
android:id="@+id/music_preferences"
app:destination="@id/music_preferences_fragment" />
<action
android:id="@+id/audio_peferences"
app:destination="@id/audio_preferences_fragment" />
<action
android:id="@+id/music_dirs_settings"
app:destination="@id/music_dirs_dialog" />
</fragment>
<fragment
android:id="@+id/ui_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.UIPreferenceFragment"
android:label="fragment_ui_preferences">
<action
android:id="@+id/accent_settings"
app:destination="@id/accent_dialog" />
</fragment>
<fragment
android:id="@+id/personalize_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.PersonalizePreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/tab_settings"
app:destination="@id/tab_dialog" />
</fragment>
<fragment
android:id="@+id/music_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.MusicPreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/separators_settings"
app:destination="@id/separators_dialog" />
</fragment>
<fragment
android:id="@+id/audio_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.AudioPreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/pre_amp_settings"
app:destination="@id/pre_amp_dialog" />
</fragment>
<dialog
android:id="@+id/accent_dialog"
android:name="org.oxycblt.auxio.ui.accent.AccentCustomizeDialog"
android:label="accent_dialog"
tools:layout="@layout/dialog_accent" />
<dialog
android:id="@+id/tab_dialog"
android:name="org.oxycblt.auxio.home.tabs.TabCustomizeDialog"
android:label="tab_dialog"
tools:layout="@layout/dialog_tabs" />
<dialog
android:id="@+id/pre_amp_dialog"
android:name="org.oxycblt.auxio.playback.replaygain.PreAmpCustomizeDialog"
android:label="pre_amp_dialog"
tools:layout="@layout/dialog_pre_amp" />
<dialog
android:id="@+id/music_dirs_dialog"
android:name="org.oxycblt.auxio.music.fs.MusicDirsDialog"
android:label="music_dirs_dialog"
tools:layout="@layout/dialog_music_dirs" />
<dialog
android:id="@+id/separators_dialog"
android:name="org.oxycblt.auxio.music.metadata.SeparatorsDialog"
android:label="music_dirs_dialog"
tools:layout="@layout/dialog_separators" />
<fragment
android:id="@+id/about_fragment"
android:name="org.oxycblt.auxio.settings.AboutFragment"
android:label="dialog_about"
tools:layout="@layout/fragment_about" />
</navigation>

View file

@ -0,0 +1,108 @@
<?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/absurd"
app:startDestination="@id/main_fragment">
<fragment
android:id="@+id/main_fragment"
android:name="org.oxycblt.auxio.MainFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main">
<action
android:id="@+id/preferences"
app:destination="@id/root_preferences_fragment" />
<action
android:id="@+id/about"
app:destination="@id/about_fragment" />
</fragment>
<fragment
android:id="@+id/root_preferences_fragment"
android:name="org.oxycblt.auxio.settings.RootPreferenceFragment"
android:label="fragment_settings">
<action
android:id="@+id/ui_preferences"
app:destination="@id/ui_preferences_fragment" />
<action
android:id="@+id/personalize_preferences"
app:destination="@id/personalize_preferences_fragment" />
<action
android:id="@+id/music_preferences"
app:destination="@id/music_preferences_fragment" />
<action
android:id="@+id/audio_peferences"
app:destination="@id/audio_preferences_fragment" />
<action
android:id="@+id/music_dirs_settings"
app:destination="@id/music_dirs_dialog" />
</fragment>
<fragment
android:id="@+id/ui_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.UIPreferenceFragment"
android:label="fragment_ui_preferences">
<action
android:id="@+id/accent_settings"
app:destination="@id/accent_dialog" />
</fragment>
<fragment
android:id="@+id/personalize_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.PersonalizePreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/tab_settings"
app:destination="@id/tab_dialog" />
</fragment>
<fragment
android:id="@+id/music_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.MusicPreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/separators_settings"
app:destination="@id/separators_dialog" />
</fragment>
<fragment
android:id="@+id/audio_preferences_fragment"
android:name="org.oxycblt.auxio.settings.categories.AudioPreferenceFragment"
android:label="fragment_personalize_preferences">
<action
android:id="@+id/pre_amp_settings"
app:destination="@id/pre_amp_dialog" />
</fragment>
<dialog
android:id="@+id/accent_dialog"
android:name="org.oxycblt.auxio.ui.accent.AccentCustomizeDialog"
android:label="accent_dialog"
tools:layout="@layout/dialog_accent" />
<dialog
android:id="@+id/tab_dialog"
android:name="org.oxycblt.auxio.home.tabs.TabCustomizeDialog"
android:label="tab_dialog"
tools:layout="@layout/dialog_tabs" />
<dialog
android:id="@+id/pre_amp_dialog"
android:name="org.oxycblt.auxio.playback.replaygain.PreAmpCustomizeDialog"
android:label="pre_amp_dialog"
tools:layout="@layout/dialog_pre_amp" />
<dialog
android:id="@+id/music_dirs_dialog"
android:name="org.oxycblt.auxio.music.fs.MusicDirsDialog"
android:label="music_dirs_dialog"
tools:layout="@layout/dialog_music_dirs" />
<dialog
android:id="@+id/separators_dialog"
android:name="org.oxycblt.auxio.music.metadata.SeparatorsDialog"
android:label="music_dirs_dialog"
tools:layout="@layout/dialog_separators" />
<fragment
android:id="@+id/about_fragment"
android:name="org.oxycblt.auxio.settings.AboutFragment"
android:label="dialog_about"
tools:layout="@layout/fragment_about" />
</navigation>