settings: use manual nav graph

Manually use our own navigation graph in the new settings view.

This avoids a crash that occurs with the default preferences navigation
(on some devices) where the differing app IDs between debug and release
makes it so that the fragments cannot be found. Because you know.
Android.
This commit is contained in:
Alexander Capehart 2023-01-20 18:38:10 -07:00
parent f2d44b40bf
commit 90843918d6
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
13 changed files with 113 additions and 102 deletions

View file

@ -34,8 +34,8 @@ android {
buildTypes {
debug {
applicationIdSuffix = ".debug"
versionNameSuffix = "-DEBUG"
applicationIdSuffix ".debug"
versionNameSuffix "-DEBUG"
}
release {

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings
import android.os.Bundle
import android.view.LayoutInflater
@ -32,6 +32,10 @@ import androidx.preference.children
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.transition.MaterialSharedAxis
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.ui.IntListPreference
import org.oxycblt.auxio.settings.ui.IntListPreferenceDialog
import org.oxycblt.auxio.settings.ui.PreferenceHeaderItemDecoration
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.systemBarInsetsCompat
@ -68,14 +72,7 @@ abstract class BasePreferenceFragment(@XmlRes private val screen: Int) :
androidx.preference.R.id.recycler_view
view.findViewById<Toolbar>(R.id.preferences_toolbar).apply {
title = preferenceScreen.title
setNavigationOnClickListener {
val fragmentManager = @Suppress("Deprecation") fragmentManager
if (fragmentManager == null || fragmentManager.backStackEntryCount == 0) {
findNavController().navigateUp()
} else {
fragmentManager.popBackStack()
}
}
setNavigationOnClickListener { findNavController().navigateUp() }
}
preferenceManager.onDisplayPreferenceDialogListener = this

View file

@ -15,16 +15,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings
import android.os.Bundle
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis
import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.showToast
@ -36,9 +39,18 @@ class RootPreferenceFragment : BasePreferenceFragment(R.xml.preferences_root) {
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
private val musicModel: MusicViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialFadeThrough()
returnTransition = MaterialFadeThrough()
exitTransition = MaterialFadeThrough()
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
}
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_music_dirs)) {
findNavController().navigate(SettingsFragmentDirections.goToMusicDirsDialog())
findNavController().navigate(RootPreferenceFragmentDirections.goToMusicDirsDialog())
}
}
@ -47,6 +59,21 @@ class RootPreferenceFragment : BasePreferenceFragment(R.xml.preferences_root) {
// TODO: These seem like good things to put into a side navigation view, if I choose to
// do one.
when (preference.key) {
getString(R.string.set_key_ui) -> {
findNavController().navigate(RootPreferenceFragmentDirections.goToUiPreferences())
}
getString(R.string.set_key_personalize) -> {
findNavController()
.navigate(RootPreferenceFragmentDirections.goToPersonalizePreferences())
}
getString(R.string.set_key_music) -> {
findNavController()
.navigate(RootPreferenceFragmentDirections.goToMusicPreferences())
}
getString(R.string.set_key_audio) -> {
findNavController()
.navigate(RootPreferenceFragmentDirections.goToAudioPreferences())
}
getString(R.string.set_key_reindex) -> musicModel.refresh()
getString(R.string.set_key_rescan) -> musicModel.rescan()
getString(R.string.set_key_save_state) -> {

View file

@ -1,42 +0,0 @@
/*
* Copyright (c) 2021 Auxio Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings
import android.os.Bundle
import android.view.LayoutInflater
import androidx.fragment.app.Fragment
import com.google.android.material.transition.MaterialFadeThrough
import org.oxycblt.auxio.databinding.FragmentSettingsBinding
import org.oxycblt.auxio.ui.ViewBindingFragment
/**
* A [Fragment] wrapper wrapping the preference navigation flow.
* @author Alexander Capehart (OxygenCobalt)
*/
class SettingsFragment : ViewBindingFragment<FragmentSettingsBinding>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialFadeThrough()
exitTransition = MaterialFadeThrough()
}
override fun onCreateBinding(inflater: LayoutInflater) =
FragmentSettingsBinding.inflate(inflater)
override fun onBindingCreated(binding: FragmentSettingsBinding, savedInstanceState: Bundle?) {}
}

View file

@ -15,11 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings.categories
import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
/**
* Audio settings interface.
@ -29,7 +30,7 @@ class AudioPreferenceFragment : BasePreferenceFragment(R.xml.preferences_audio)
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_pre_amp)) {
findNavController().navigate(SettingsFragmentDirections.goToPreAmpDialog())
findNavController().navigate(AudioPreferenceFragmentDirections.goToPreAmpDialog())
}
}
}

View file

@ -15,13 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings.categories
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import coil.Coil
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
/**
* "Content" settings.
@ -30,7 +31,7 @@ import org.oxycblt.auxio.settings.SettingsFragmentDirections
class MusicPreferenceFragment : BasePreferenceFragment(R.xml.preferences_music) {
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_separators)) {
findNavController().navigate(SettingsFragmentDirections.goToSeparatorsDialog())
findNavController().navigate(MusicPreferenceFragmentDirections.goToSeparatorsDialog())
}
}

View file

@ -15,11 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings.categories
import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
/**
* Personalization settings interface.
@ -28,7 +29,7 @@ import org.oxycblt.auxio.settings.SettingsFragmentDirections
class PersonalizePreferenceFragment : BasePreferenceFragment(R.xml.preferences_personalize) {
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_home_tabs)) {
findNavController().navigate(SettingsFragmentDirections.goToTabDialog())
findNavController().navigate(PersonalizePreferenceFragmentDirections.goToTabDialog())
}
}
}

View file

@ -15,20 +15,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.settings.ui
package org.oxycblt.auxio.settings.categories
import androidx.appcompat.app.AppCompatDelegate
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.ui.UISettings
import org.oxycblt.auxio.util.isNight
class UIPreferenceFragment : BasePreferenceFragment(R.xml.preferences_ui) {
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_accent)) {
findNavController().navigate(SettingsFragmentDirections.goToAccentDialog())
findNavController().navigate(UIPreferenceFragmentDirections.goToAccentDialog())
}
}

View file

@ -17,6 +17,7 @@
package org.oxycblt.auxio.settings.ui
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import androidx.preference.PreferenceCategory
@ -39,6 +40,7 @@ constructor(
defStyleAttr: Int = R.attr.materialDividerStyle,
orientation: Int = LinearLayoutManager.VERTICAL
) : BackportMaterialDividerItemDecoration(context, attributeSet, defStyleAttr, orientation) {
@SuppressLint("RestrictedApi")
override fun shouldDrawDivider(position: Int, adapter: RecyclerView.Adapter<*>?) =
try {
// Add a divider if the next item is a header (in this case a preference category

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
android:transitionGroup="true">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/settings_list_fragment"
android:name="org.oxycblt.auxio.settings.ui.RootPreferenceFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
tools:layout="@android:layout/preference_category" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -10,7 +10,7 @@
tools:layout="@layout/fragment_main">
<action
android:id="@+id/action_show_settings"
app:destination="@id/settings_fragment" />
app:destination="@id/root_preferences_fragment" />
<action
android:id="@+id/action_show_about"
app:destination="@id/about_fragment" />
@ -68,27 +68,64 @@
app:argType="org.oxycblt.auxio.music.Music$UID" />
</dialog>
<fragment
android:id="@+id/settings_fragment"
android:name="org.oxycblt.auxio.settings.SettingsFragment"
android:label="fragment_settings"
tools:layout="@layout/fragment_settings">
android:id="@+id/root_preferences_fragment"
android:name="org.oxycblt.auxio.settings.RootPreferenceFragment"
android:label="fragment_settings">
<action
android:id="@+id/go_to_accent_dialog"
app:destination="@id/accent_dialog" />
android:id="@+id/go_to_ui_preferences"
app:destination="@id/ui_preferences_fragment" />
<action
android:id="@+id/go_to_tab_dialog"
app:destination="@id/tab_dialog" />
android:id="@+id/go_to_personalize_preferences"
app:destination="@id/personalize_preferences_fragment" />
<action
android:id="@+id/go_to_pre_amp_dialog"
app:destination="@id/pre_amp_dialog" />
android:id="@+id/go_to_music_preferences"
app:destination="@id/music_preferences_fragment" />
<action
android:id="@+id/go_to_audio_preferences"
app:destination="@id/audio_preferences_fragment" />
<action
android:id="@+id/go_to_music_dirs_dialog"
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/go_to_accent_dialog"
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/go_to_tab_dialog"
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/go_to_separators_dialog"
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/go_to_pre_amp_dialog"
app:destination="@id/pre_amp_dialog" />
</fragment>
<dialog
android:id="@+id/accent_dialog"
android:name="org.oxycblt.auxio.ui.accent.AccentCustomizeDialog"

View file

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Note: The old way of naming keys was to prefix them with KEY_. Now it's to prefix them with auxio_. -->
<string name="set_key_ui" translatable="false">auxio_ui</string>
<string name="set_key_personalize" translatable="false">auxio_personalize</string>
<string name="set_key_music" translatable="false">auxio_music</string>
<string name="set_key_audio" translatable="false">auxio_audio</string>
<string name="set_key_theme" translatable="false">KEY_THEME2</string>
<string name="set_key_black_theme" translatable="false">KEY_BLACK_THEME</string>
<string name="set_key_accent" translatable="false">auxio_accent2</string>

View file

@ -3,26 +3,26 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/set_root_title">
<Preference
app:fragment="org.oxycblt.auxio.settings.ui.UIPreferenceFragment"
app:icon="@drawable/ic_accent_24"
app:key="@string/set_key_ui"
app:summary="@string/set_ui_desc"
app:title="@string/set_ui" />
<Preference
app:fragment="org.oxycblt.auxio.settings.ui.PersonalizePreferenceFragment"
app:icon="@drawable/ic_config_24"
app:key="@string/set_key_personalize"
app:summary="@string/set_personalize_desc"
app:title="@string/set_personalize" />
<Preference
app:fragment="org.oxycblt.auxio.settings.ui.MusicPreferenceFragment"
app:icon="@drawable/ic_song_24"
app:key="@string/set_key_music"
app:summary="@string/set_content_desc"
app:title="@string/set_content" />
<Preference
app:fragment="org.oxycblt.auxio.settings.ui.AudioPreferenceFragment"
app:icon="@drawable/ic_play_24"
app:key="@string/set_key_audio"
app:summary="@string/set_audio_desc"
app:title="@string/set_audio" />