why is Navigation Component fragment Label not working - android

hello i am changing the label of fragment in navigation file but the fragment title in the tool bar isn't changing, any solution?
<fragment
android:id="#+id/navHostFragment"
android:name="com.example.androidtask.view.UsersList"
android:label="#string/user_list"
tools:layout="#layout/fragment_users_list">
<action
android:id="#+id/submit_user"
app:destination="#id/addUser" />
</fragment>

you need to setup ActionBar to work with navigation , add this code in activity onCreate()
val navController = findNavController(R.id.nav_host_fragment)// where nav_host_fragment is the id for your Main NavHost fragment
val appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
for more info check this

Related

Navigation in Bottom Navigaiton View creates/destroys the fragment Navigation 2.4.2

I am using the latest Navigation version 2.4.2.
I set up the bottom nav bar with the Navigation component as follow, the same way recommended by google:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
My menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/title_home" />
<item
android:id="#+id/navigation_dashboard"
android:icon="#drawable/ic_dashboard_black_24dp"
android:title="#string/title_dashboard"
xmlns:app="http://schemas.android.com/apk/res-auto" />
<item
android:id="#+id/navigation_notifications"
android:icon="#drawable/ic_notifications_black_24dp"
android:title="#string/title_notifications" />
However, when I navigate from one fragment to the other, its onDestroy() is called and when I navigate back to it is recreated.
This is the case for all the fragment in the BottomNavView except the startDestination. The onCreate() for the startDestination is called only once and when navigating away from it, only the onDestroyView() is called. I want this behavior for all the other fragments as well as I need to put code in the onCreate() method and want it to run once once per lifecycle of the app.
Support for multiple backstack arrive with Navigation 2.4.0 so I don't know what's wrong. when calling findNavController.navigate(...), the previous fragment is kept in the backstack and is not destroyed(), and as far as I know the BottomNavBar calls the same method so I can't figure out why each fragment is being created/destroyed upon each navigation.
Me navigating from : Start Fragment -> Dashboard Fragment -> Navigation Fragment -> Start Fragment
All the fragment except the Start Fragment is recreated.
Any help is appreciated.
For anyone looking for an answer to this question. Google replied that it is expected behaviour.
https://issuetracker.google.com/issues/190893266

How to get navController inside activity?

I use Jetpack Navigation for navigating between fragments and activity. So, I have a MainActivity with a FragmentContainerView in the layout. I can easily navigate from fragment to fragment/activity. But, I can't find a way how to navigate from one activity to another activity/fragment with navController.
For example, from fragment FA, I call navController.navigate() to activity A. Now, I want to navigate from activity A to activity B or fragment FB.
I already tried this:
val host = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = host.navController
But always got this error
null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment
Thanks!
A note from the navigation component guide
Note: The Navigation component is designed for apps that have one main activity with multiple fragment destinations. The main activity is associated with a navigation graph and contains a NavHostFragment that is responsible for swapping destinations as needed. In an app with multiple activity destinations, each activity has its own navigation graph.
You shouldn't use the navigation component to navigate from one activity to another. It is made to swap fragments on a Fragment container.
You can get navController inside activity using
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
You also have to add android:name="androidx.navigation.fragment.NavHostFragment" to your fragment container
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
For java coder;
it is possible to get NavController instance this way
NavHostFragment navHostFragment =(NavHostFragment)getSupportFragmentManager()
.findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

How can i change the text in the app bar?

I am currently working on an app that requires the navigation template from creation. I have been fine-tuning the look of the default navigation template for the app I need to work on. However, there's one thing I have been unable to find a solution to which is to change the text in the app bar. It keeps saying 'Home' but I need to put the title of my app there. I have tried several things such as: setTitle("App title here") in the mainActivity, and in the manifest file I have also tried changing the text in android:label to the App title but nothing I do from the solutions I find online seems to work.
Is there any way I can get around this and change the 'home' text into my App's title? Thanks in advance for any suggestions.
Code inside OnCreate as requested in a comment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTitle("Simple Dark Calculator")
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
Check the doc:
NavigationUI uses the destination labels from your navigation graph to keep the title of the top app bar up-to-date.
In your navigation graph change the android:label of the startDestination.
<navigation
app:startDestination="#+id/nav_home">
<fragment
android:id="#+id/nav_home"
android:label="#string/menu_home"
... >
</fragment>
You can also use the OnDestinationChangedListener to set the title after your setup method:
navController.addOnDestinationChangedListener { controller, destination, arguments ->
if (destination.id == R.id.nav_xxx){
supportActionBar?.title = "My Title"
}
//.....
}
Try to remove setTitle("Simple Dark Calculator") line and add code below after setSupportActionBar method:
getSupportActionBar().setTitle("Simple Dark Calculator");
To read more about setting up the app bar:
Set up the app bar
Try this in Manifest:
<activity android:name=".Youractivityname"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize"/>

Pass arguments from fragment to another activity

I'm using the navigation controller for navigating. I need to navigate from the current fragment to a different activity and pass it some data. This has been problematic. Navigating to the activity works but the arguments are null. Here is the global action I am using in my navigation graph:
<action android:id="#+id/sign_out"
app:destination="#id/login_activity">
<argument
android:name="clearSession"
app:argType="boolean"
android:defaultValue="true"/>
</action>
<activity android:id="#+id/login_activity"
android:name="com.example.ui.login.LoginActivity"
android:label="loginActivity">
<argument
android:name="clearSession"
app:argType="boolean"
android:defaultValue="true"/>
</activity>
And the menu navigation item:
<item android:title="#string/app">
<menu>
<group android:checkableBehavior="single">
<item
android:id="#+id/sign_out"
android:icon="#drawable/ic_exit_to_app"
android:title="#string/sign_out"/>
</group>
</menu>
</item>
Code for setting up navigation:
navController = Navigation.findNavController(this, R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(R.id.connections_fragment, R.id.search_fragment), drawerLayout)
// Set up ActionBar
setSupportActionBar(binding.toolbar)
setupActionBarWithNavController(navController, appBarConfiguration)
// Set up navigation menu
binding.navigationView.setupWithNavController(navController)
I'm using a navigation drawer and a menu item in the navigation view has its id set to "sign_out". Clicking on this menu item will cause the Login screen to be loaded but the arguments are not provided even though they are specified in both the action and the destination. The navigation controller does not appear to be sending the arguments when it launches the Login activity and I suspect that this is a bug in Android. There are virtually no posts in Stackoverflow showing users passing data from a fragment to a different activity.
Is your sign_out action inside <fragment> tag?
If so you can call use navigate() method:
val bundle = Bundle().apply { putString("EXTRA_KEY", "EXTRA_VALUE") }
findNavController().navigate(R.id.sign_out, bundle)
And then val stringExtra = intent.getStringExtra("EXTRA_KEY") in LoginActivity

Android Architechture Navigation - onSupportNavigateUp()

While using Navigation Library, is it okay to finish the inner activity with finish() in onSupportNavigateUp()? Or we should use NavController to remove that Activity from Stack? And, I have trouble using NavController to remove Activity.
My Navigation graph looks like below:
<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"
app:startDestination="#id/home_frag">
<fragment
android:id="#+id/home_frag"
android:name="com.yamikrish.app.slicedemo.ui.home.HomeFragment"
android:label="home_frag"
tools:layout="#layout/home_fragment">
<action
android:id="#+id/open_details"
app:destination="#id/details_fragment" />
</fragment>
<activity
android:id="#+id/details_fragment"
android:name="com.yamikrish.app.slicedemo.ui.detail.DetailActivity"
android:label="#string/post_detail"
tools:layout="#layout/detail_page">
<argument
android:name="id"
app:type="integer" />
</activity>
<fragment
android:id="#+id/profile_frag"
android:name="com.yamikrish.app.slicedemo.ui.profile.ProfileFragment"
android:label="#string/profile"
tools:layout="#layout/profile_fragment" />
</navigation>
I have tried to use like below:
(i) Using NavController inside DetailActivity
override fun onSupportNavigateUp(): Boolean {
val nav = NavController(this)
return nav.navigateUp()
}
But getting exception as,
java.lang.IllegalArgumentException: NavController back stack is empty
(ii) Using NavController inside BaseActivity
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.container).navigateUp()
}
That also not working. Am I doing it wrong??
Your detail activity has no concept of the parent nav graph in this case. You example ii is correct. Since BaseActivity contains a navigation graph. I don't know what the DetailActivity is doing but if it also contains a navigation graph then you should use the same code as your BaseActivity. The fact that you're getting that error and also creating a new NavController on the fly tells me that DetailActivity is not using a navigation graph (creating a new NavController and not providing it with a graph will by default initialize with an empty back stack).
In summary, DetailActivity's onSupportNavigateUp should behave like a normal up navigation. If there's a clear parent you should launch it, otherwise, just finish().

Categories

Resources