Navigation component: Retain same fragment after orientation change - android

as I said in the title, I would like to keep my current fragment after rotating the phone. I could actually make it happen by adding
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
in the Manifest. The problem is that my layout configuration is lost every time.
What am I doing wrong? How can I fix it?
I'm using Jetpack Navigation component. Exist a way to navigateToCurrentFragment()?
Edit: Part of onCreate() from Activity()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
val graphInflater = (supportFragmentManager.findFragmentById(R.id.mNavHost) as NavHostFragment).navController.navInflater
val navGraph = graphInflater.inflate(R.navigation.services_nav_graph)
navGraph.startDestination = R.id.FirstFragment
(supportFragmentManager.findFragmentById(R.id.mNavHost) as NavHostFragment).navController.graph = navGraph
}

Related

Android app dev: Waterfall management for the app

I would like my Android app to manage waterfall displays automatically if present, in that I do not wish for the texts, buttons, etc to be displayed all the way to the screen's border if the screen is waterfall, as I find this not to be user friendly.
I've tried to explicitely state the WindowCompat true, but that doesn't seem to help
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
context = this
sharedPref = getSharedPreferences("app_settings", Context.MODE_PRIVATE)
WindowCompat.setDecorFitsSystemWindows(window, true)
super.onCreate(savedInstanceState)
setContent {
I've also tried to to put the WindowCompat to false and manually add an instet padding to WindowInsets.waterfall without any success
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
context = this
sharedPref = getSharedPreferences("app_settings", Context.MODE_PRIVATE)
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
setContent {
myTheme(chosenTheme = themeSelection.value) {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier
.windowInsetsPadding(WindowInsets.waterfall),
Any clue as to what I am doing wrong ?
Is there a way to fix this at the same level as WindowCompat, so that it's valid for the full app?
Thanks!

Handling different startDestination in android single activity Navigation graph

I want to implement a single activity project.
After showing splash i want to navigate to HomeFragment or LoginFragment based on user's login condition. In the MainActivity :
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (userLoggedIn()) {
navigateToHomeScreen()
} else {
navigateToLoginScreen()
}
}
The question is how should i set the navigation xml? Which one of the fragments should be the startDestionation. What's the best approach for a smooth splash/login( sign-in/sign-up/forget-pass)/ home flow.

android navigation graph configration change

I am trying to follow single activity pattern with android navigation component and my %99 of fragment are portrait but I need to make a new fragment can be portrait or landscape without adding new activity how can I achieve. I could't find any resource. is it possible ? if it is how ?
You can add NavController.OnDestinationChangedListener and set orientation according to the current fragment.
Add this in your activity's onCreate:
val navHostFragment = supportFragmentManager.findFragmentById(R.id.your_nav_host_fragment) as NavHostFragment
navHostFragment.navController..addOnDestinationChangedListener { _, destination, _ ->
if (destination.id == R.id.destination_with_orientation) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
} else {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}
The following steps could be useful for you:
Don't lock screen orientation from AndroidManifest.xml.
Register a listener inside Activity on the childFragmentManager of the NavHostFragment, that will execute callbacks on fragment lifecycle change
override fun onCreate(savedInstanceState: Bundle?) {
//...
val fragments = supportFragmentManager.fragments
check(fragments.size == 1) {
val baseMessage = "Expected 1 fragment to host the app's navigation. Instead found ${fragments.size}."
if (fragments.size == 0) {
val suggestion = "(Make sure you specify `android:name=\"androidx.navigation.fragment." +
"NavHostFragment\"` or override setUpNavigationGraph)"
"$baseMessage $suggestion"
} else baseMessage
}
with(fragments[0].childFragmentManager) {
registerFragmentLifecycleCallbacks(CustomFragmentLifecycleCallbacks(), false)
}
}
private inner class CustomFragmentLifecycleCallbacks : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) {}
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {}
}
Follow this guide to lock/unlock screen orientation depending upon which Fragment is visible, from the above callback.
NOTE
Fragment tags or instance type could be used for writing conditional statements inside the lifecycle callbacks, based on app's navigation design.
Don't forget to unregisterFragmentLifecycleCallbacks from Activity.onDestroy()
Cheers 🍻

Navigating to fragment doesn't Work - Kotlin

I was trying to open some fragment however the app keep crashing
I am wondering if it was possible to fix the issue that I got
class HomePage : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_page)
val addMed = findViewById<Button>(R.id.addMedButton)
val fragManager: FragmentManager = supportFragmentManager
fragManager.beginTransaction().add(R.id.frameLayout, addMed).commit()
}
}
You have to add a fragment, not a button.
Besides, if the button is found by id, it is already present in the activity.

How to show the fragment's enterTransition above the exitTransition

I want to show the enterTransition on top of the exitTransition.
But as you can see in the gif, the enterTransition is below the exitTransition.
How can I solve this problem?
The navigation component is used for fragment transitions.
EnterFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = Slide().apply {
duration = 2000
slideEdge = Gravity.END
}
}
ExitFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = Slide().apply {
duration= 3000
slideEdge = Gravity.START
}
}
nav_main.xml
<action
android:id="#+id/move"
app:destination="#id/fragment_enter"
/>
Please refer to the official documentation for transition animations with navigation component: https://developer.android.com/guide/navigation/navigation-animate-transitions
You will need to put your animations in a respective animation xml file and then reference it in your nav_graph xml within the respective action. You can then specify when which animation should be used.

Categories

Resources