Skip to content

Commit 390c68d

Browse files
committed
Fixed navigation fragments transitions
1 parent a947251 commit 390c68d

29 files changed

+288
-235
lines changed

app/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,12 @@ android {
5656

5757
dependencies {
5858
implementation(libs.kotlin.reflect)
59+
implementation(libs.androidx.activity)
60+
implementation(libs.androidx.fragment)
5961
implementation(libs.androidx.preference)
6062
implementation(libs.androidx.appcompat)
6163
implementation(libs.androidx.navigation)
64+
implementation(libs.androidx.transition)
6265
implementation(libs.androidx.splashscreen)
6366
implementation(libs.google.material)
6467
implementation(libs.aboutlibraries.view)

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
<activity
3131
android:name=".activity.MainActivity"
32-
android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
32+
android:configChanges="screenSize|keyboard|keyboardHidden"
3333
android:exported="true"
3434
android:launchMode="singleTop"
3535
android:theme="@style/AppThemeSplash">
@@ -46,7 +46,7 @@
4646

4747
<activity
4848
android:name=".activity.LibraryActivity"
49-
android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
49+
android:configChanges="screenSize|keyboard|keyboardHidden"
5050
android:exported="false"
5151
android:launchMode="singleTop"
5252
android:theme="@style/AppTheme.Library" />
@@ -471,7 +471,7 @@
471471

472472
<activity
473473
android:name=".activity.AssistantSelectorActivity"
474-
android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
474+
android:configChanges="screenSize|keyboard|keyboardHidden"
475475
android:excludeFromRecents="true"
476476
android:exported="false"
477477
android:launchMode="singleTop"

app/src/main/java/com/wstxda/switchai/activity/BaseActivity.kt

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@ import android.os.Build
55
import android.os.Bundle
66
import android.view.Menu
77
import android.view.MenuItem
8-
import android.view.View
98
import androidx.activity.SystemBarStyle
109
import androidx.activity.enableEdgeToEdge
1110
import androidx.appcompat.app.AppCompatActivity
1211
import androidx.appcompat.widget.Toolbar
1312
import androidx.core.content.pm.ShortcutManagerCompat
14-
import androidx.core.view.ViewCompat
15-
import androidx.core.view.WindowInsetsCompat
1613

1714
abstract class BaseActivity : AppCompatActivity() {
1815
override fun onCreate(savedInstanceState: Bundle?) {
@@ -25,7 +22,9 @@ abstract class BaseActivity : AppCompatActivity() {
2522
setSupportActionBar(toolbar)
2623
supportActionBar?.setDisplayHomeAsUpEnabled(showBackButton)
2724
if (showBackButton) {
28-
toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }
25+
toolbar.setNavigationOnClickListener {
26+
onBackPressedDispatcher.onBackPressed()
27+
}
2928
}
3029
}
3130

@@ -35,16 +34,8 @@ abstract class BaseActivity : AppCompatActivity() {
3534
navigationBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT)
3635
)
3736
window.isNavigationBarContrastEnforced = false
38-
}
39-
}
40-
41-
protected fun applySystemBarInsets(target: View) {
42-
ViewCompat.setOnApplyWindowInsetsListener(target) { view, insets ->
43-
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
44-
view.setPadding(
45-
systemBarsInsets.left, 0, systemBarsInsets.right, systemBarsInsets.bottom
46-
)
47-
WindowInsetsCompat.CONSUMED
37+
} else {
38+
enableEdgeToEdge()
4839
}
4940
}
5041

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,16 @@
11
package com.wstxda.switchai.activity
22

33
import android.os.Bundle
4-
import android.view.MenuItem
54
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
6-
import androidx.navigation.NavController
7-
import androidx.navigation.fragment.NavHostFragment
8-
import com.wstxda.switchai.R
95
import com.wstxda.switchai.databinding.ActivityMainBinding
10-
import com.wstxda.switchai.ui.component.AssistantTutorialBottomSheet
116

127
class MainActivity : BaseActivity() {
138

149
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
15-
private lateinit var navController: NavController
1610

1711
override fun onCreate(savedInstanceState: Bundle?) {
1812
installSplashScreen()
1913
super.onCreate(savedInstanceState)
2014
setContentView(binding.root)
21-
applySystemBarInsets(binding.navHostContainer)
22-
23-
setupToolbar(binding.toolbar, showBackButton = false)
24-
setupNavController()
25-
}
26-
27-
override fun onDestroy() {
28-
super.onDestroy()
29-
navController.removeOnDestinationChangedListener(destinationChangedListener)
30-
}
31-
32-
private fun setupNavController() {
33-
val navHostFragment =
34-
supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
35-
navController = navHostFragment.navController
36-
37-
navController.addOnDestinationChangedListener(destinationChangedListener)
38-
}
39-
40-
private val destinationChangedListener =
41-
NavController.OnDestinationChangedListener { controller, destination, _ ->
42-
val label = destination.label?.toString() ?: getString(R.string.app_settings)
43-
binding.collapsingToolbar.title = label
44-
45-
val isTopLevel = destination.id == controller.graph.startDestinationId
46-
supportActionBar?.setDisplayHomeAsUpEnabled(!isTopLevel)
47-
binding.toolbar.setNavigationOnClickListener {
48-
if (!isTopLevel) onBackPressedDispatcher.onBackPressed()
49-
}
50-
}
51-
52-
override fun getMenuResId(): Int = R.menu.main_menu
53-
54-
override fun onMenuItemSelected(item: MenuItem): Boolean {
55-
return when (item.itemId) {
56-
R.id.action_show_tutorial -> {
57-
AssistantTutorialBottomSheet.show(supportFragmentManager)
58-
true
59-
}
60-
61-
else -> false
62-
}
6315
}
6416
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.wstxda.switchai.fragment
2+
3+
import android.os.Bundle
4+
import android.view.LayoutInflater
5+
import android.view.View
6+
import android.view.ViewGroup
7+
import androidx.annotation.XmlRes
8+
import androidx.core.view.ViewCompat
9+
import androidx.core.view.WindowInsetsCompat
10+
import androidx.navigation.fragment.findNavController
11+
import androidx.preference.PreferenceFragmentCompat
12+
import androidx.recyclerview.widget.RecyclerView
13+
import com.google.android.material.appbar.MaterialToolbar
14+
import com.google.android.material.color.MaterialColors
15+
import com.google.android.material.transition.MaterialSharedAxis
16+
import com.wstxda.switchai.R
17+
import com.wstxda.switchai.databinding.FragmentPreferencesBinding
18+
19+
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
20+
21+
private var _binding: FragmentPreferencesBinding? = null
22+
protected val binding get() = _binding!!
23+
24+
@get:XmlRes
25+
protected abstract val preferencesResId: Int
26+
27+
override fun onCreate(savedInstanceState: Bundle?) {
28+
super.onCreate(savedInstanceState)
29+
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
30+
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
31+
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
32+
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
33+
}
34+
35+
override fun onCreateView(
36+
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
37+
): View {
38+
_binding = FragmentPreferencesBinding.inflate(inflater, container, false)
39+
val prefsContainer = binding.preferencesContainer
40+
prefsContainer.addView(super.onCreateView(inflater, prefsContainer, savedInstanceState))
41+
return binding.root
42+
}
43+
44+
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
45+
setPreferencesFromResource(preferencesResId, rootKey)
46+
}
47+
48+
override fun onCreateRecyclerView(
49+
inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle?
50+
): RecyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState).apply {
51+
isVerticalScrollBarEnabled = false
52+
clipToPadding = false
53+
applySystemBarInsets(this)
54+
}
55+
56+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
57+
super.onViewCreated(view, savedInstanceState)
58+
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.colorBackground))
59+
setupViews()
60+
setupToolbar()
61+
setupListeners()
62+
setupObservers()
63+
}
64+
65+
protected open fun setupViews() {}
66+
67+
protected open fun setupToolbar() {
68+
val collapsingToolbar = binding.collapsingToolbar
69+
val toolbar = binding.toolbar
70+
val appBar = binding.appBar
71+
72+
collapsingToolbar.title = getToolbarTitle()
73+
74+
if (showNavigationIcon()) {
75+
toolbar.setNavigationIcon(R.drawable.ic_back)
76+
toolbar.setNavigationOnClickListener { findNavController().navigateUp() }
77+
} else {
78+
toolbar.navigationIcon = null
79+
}
80+
81+
onToolbarCreated(toolbar)
82+
83+
appBar.setLiftOnScrollTargetView(listView)
84+
}
85+
86+
protected open fun setupListeners() {}
87+
protected open fun setupObservers() {}
88+
89+
protected open fun getToolbarTitle(): String =
90+
findNavController().currentDestination?.label?.toString() ?: ""
91+
92+
protected open fun showNavigationIcon(): Boolean = true
93+
94+
protected open fun onToolbarCreated(toolbar: MaterialToolbar) = Unit
95+
96+
protected fun applySystemBarInsets(target: View) {
97+
ViewCompat.setOnApplyWindowInsetsListener(target) { v, insets ->
98+
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
99+
v.setPadding(
100+
systemBarsInsets.left, 0, systemBarsInsets.right, systemBarsInsets.bottom
101+
)
102+
WindowInsetsCompat.CONSUMED
103+
}
104+
}
105+
106+
override fun onDestroyView() {
107+
super.onDestroyView()
108+
_binding = null
109+
}
110+
111+
override fun onDestroy() {
112+
super.onDestroy()
113+
requireContext().theme.applyStyle(R.style.AppTheme, true)
114+
}
115+
}

app/src/main/java/com/wstxda/switchai/fragment/preferences/AboutPreferencesFragment.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
package com.wstxda.switchai.fragment.preferences
22

33
import android.content.Intent
4-
import android.os.Bundle
54
import androidx.core.net.toUri
65
import androidx.fragment.app.viewModels
76
import androidx.preference.Preference
87
import com.wstxda.switchai.R
98
import com.wstxda.switchai.activity.LibraryActivity
9+
import com.wstxda.switchai.fragment.BasePreferenceFragment
1010
import com.wstxda.switchai.utils.Constants
1111
import com.wstxda.switchai.viewmodel.AboutViewModel
1212

13-
class AboutPreferencesFragment : BasePreferencesFragment() {
13+
class AboutPreferencesFragment : BasePreferenceFragment() {
1414

1515
private val aboutViewModel: AboutViewModel by viewModels()
1616

17-
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
18-
setPreferencesFromResource(R.xml.preferences_about, rootKey)
17+
override val preferencesResId: Int get() = R.xml.preferences_about
18+
19+
override fun setupListeners() {
1920
setupLibraryPreference()
2021
setupLinkPreferences()
2122
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package com.wstxda.switchai.fragment.preferences
22

3-
import android.os.Bundle
43
import com.wstxda.switchai.R
4+
import com.wstxda.switchai.fragment.BasePreferenceFragment
55

6-
class AccessibilityPreferencesFragment : BasePreferencesFragment() {
6+
class AccessibilityPreferencesFragment : BasePreferenceFragment() {
77

8-
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
9-
setPreferencesFromResource(R.xml.preferences_accessibility, rootKey)
10-
}
8+
override val preferencesResId: Int get() = R.xml.preferences_accessibility
119
}

app/src/main/java/com/wstxda/switchai/fragment/preferences/AppearancePreferencesFragment.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
package com.wstxda.switchai.fragment.preferences
22

3-
import android.os.Bundle
43
import androidx.fragment.app.activityViewModels
54
import androidx.preference.ListPreference
65
import com.wstxda.switchai.R
6+
import com.wstxda.switchai.fragment.BasePreferenceFragment
77
import com.wstxda.switchai.utils.Constants
88
import com.wstxda.switchai.viewmodel.SettingsViewModel
99

10-
class AppearancePreferencesFragment : BasePreferencesFragment() {
10+
class AppearancePreferencesFragment : BasePreferenceFragment() {
1111

1212
private val settingsViewModel: SettingsViewModel by activityViewModels()
1313

14-
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
15-
setPreferencesFromResource(R.xml.preferences_appearance, rootKey)
16-
setupThemePreference()
17-
}
14+
override val preferencesResId: Int get() = R.xml.preferences_appearance
1815

19-
private fun setupThemePreference() {
16+
override fun setupListeners() {
2017
findPreference<ListPreference>(Constants.THEME_PREF_KEY)?.setOnPreferenceChangeListener { _, newValue ->
2118
settingsViewModel.applyTheme(newValue.toString())
2219
true

app/src/main/java/com/wstxda/switchai/fragment/preferences/BasePreferencesFragment.kt

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)