Is it possible to set startDestination conditionally using Android Navigation Architecture Component(Android...
I am using Navigation from Android Jetpack to navigate between screens.
Now I want to set startDestination dynamically.
I have an Activity named MainActivity
And two Fragments, FragmentA & FragmentB.
var isAllSetUp : Boolean = // It is dynamic and I’m getting this from Preferences.
If(isAllSetUp)
{
// show FragmentA
}
else
{
//show FragmentB
}
I want to set above flow using Navigation Architecture Component. Currently I have used startDestionation as below but it’s not fulfilling my requirement.
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" />
</navigation>
Is it possible to set startDestination conditionally using Android Navigation Architecture Component?
android navigation jetpack
add a comment |
I am using Navigation from Android Jetpack to navigate between screens.
Now I want to set startDestination dynamically.
I have an Activity named MainActivity
And two Fragments, FragmentA & FragmentB.
var isAllSetUp : Boolean = // It is dynamic and I’m getting this from Preferences.
If(isAllSetUp)
{
// show FragmentA
}
else
{
//show FragmentB
}
I want to set above flow using Navigation Architecture Component. Currently I have used startDestionation as below but it’s not fulfilling my requirement.
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" />
</navigation>
Is it possible to set startDestination conditionally using Android Navigation Architecture Component?
android navigation jetpack
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Try thisNavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
1
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33
add a comment |
I am using Navigation from Android Jetpack to navigate between screens.
Now I want to set startDestination dynamically.
I have an Activity named MainActivity
And two Fragments, FragmentA & FragmentB.
var isAllSetUp : Boolean = // It is dynamic and I’m getting this from Preferences.
If(isAllSetUp)
{
// show FragmentA
}
else
{
//show FragmentB
}
I want to set above flow using Navigation Architecture Component. Currently I have used startDestionation as below but it’s not fulfilling my requirement.
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" />
</navigation>
Is it possible to set startDestination conditionally using Android Navigation Architecture Component?
android navigation jetpack
I am using Navigation from Android Jetpack to navigate between screens.
Now I want to set startDestination dynamically.
I have an Activity named MainActivity
And two Fragments, FragmentA & FragmentB.
var isAllSetUp : Boolean = // It is dynamic and I’m getting this from Preferences.
If(isAllSetUp)
{
// show FragmentA
}
else
{
//show FragmentB
}
I want to set above flow using Navigation Architecture Component. Currently I have used startDestionation as below but it’s not fulfilling my requirement.
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" />
</navigation>
Is it possible to set startDestination conditionally using Android Navigation Architecture Component?
android navigation jetpack
android navigation jetpack
edited Feb 1 at 13:31
Dhruv Mevada
7502928
7502928
asked Aug 20 '18 at 10:59
Akash PatelAkash Patel
231113
231113
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Try thisNavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
1
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33
add a comment |
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Try thisNavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
1
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Try this
NavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
Try this
NavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
1
1
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33
add a comment |
3 Answers
3
active
oldest
votes
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = home_nav_fragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_main)
graph.setDefaultArguments(intent.extras)
graph.startDestination = R.id.fragment1
//or
//graph.startDestination = R.id.fragment2
navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph = inflater.inflate(R.navigation.nav_main);
graph.setDefaultArguments(getIntent().getExtras());
graph.setStartDestination(R.id.fragment1);
navHostFragment.getNavController().setGraph(graph);
navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras());
NavigationView navigationView = findViewById(R.id.navigationView);
NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set thenavHostFragment
as the default nav host. This can be accomplished with this transaction:supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
add a comment |
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host);
NavController navController = navHost.getNavController();
NavInflater navInflater = navController.getNavInflater();
NavGraph graph = navInflater.inflate(R.navigation.navigation_main);
if (false) {
graph.setStartDestination(R.id.oneFragment);
} else {
graph.setStartDestination(R.id.twoFragment);
}
navController.setGraph(graph);
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<!-- Following line omitted inside <fragment> -->
<!-- app:navGraph="@navigation/navigation_main" -->
<fragment
android:id="@+id/fragment_main_nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<!-- Following line omitted inside <navigation>-->
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main"
>
<fragment
android:id="@+id/oneFragment"
android:name="com.apponymous.apponymous.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one"/>
<fragment
android:id="@+id/twoFragment"
android:name="com.apponymous.apponymous.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two"/>
</navigation>
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, fromtwoFragment
back tooneFragment
, removingtwoFragment
from the back stack? I mean, the Navigation API equivalent ofgetSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to putsetSupportActionBar()
andNavigationUI.setupWithNavController()
? Thanks 😊
– Yan Karin
Feb 5 at 11:15
add a comment |
This can be done with navigation action. Because fragmentA is your start destination, so define an action in fragmentA.
Note these two fields:
app:popUpToInclusive="true" app:popUpTo="@id/fragmentA"
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_a_to_b"
app:destination="@id/fragmentB"
app:popUpToInclusive="true"
app:popUpTo="@id/fragmentA"/>
<fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.mindinventory.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b"/>
</navigation>
When your MainActivity started, just do the navigation with action id, it will remove fragmentA in the stack, and jump to fragmentB. Seemingly, fragmentB is your start destination.
if(!isAllSetUp)
{
// FragmentB
navController.navigate(R.id.action_a_to_b)
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51929290%2fis-it-possible-to-set-startdestination-conditionally-using-android-navigation-ar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = home_nav_fragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_main)
graph.setDefaultArguments(intent.extras)
graph.startDestination = R.id.fragment1
//or
//graph.startDestination = R.id.fragment2
navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph = inflater.inflate(R.navigation.nav_main);
graph.setDefaultArguments(getIntent().getExtras());
graph.setStartDestination(R.id.fragment1);
navHostFragment.getNavController().setGraph(graph);
navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras());
NavigationView navigationView = findViewById(R.id.navigationView);
NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set thenavHostFragment
as the default nav host. This can be accomplished with this transaction:supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
add a comment |
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = home_nav_fragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_main)
graph.setDefaultArguments(intent.extras)
graph.startDestination = R.id.fragment1
//or
//graph.startDestination = R.id.fragment2
navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph = inflater.inflate(R.navigation.nav_main);
graph.setDefaultArguments(getIntent().getExtras());
graph.setStartDestination(R.id.fragment1);
navHostFragment.getNavController().setGraph(graph);
navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras());
NavigationView navigationView = findViewById(R.id.navigationView);
NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set thenavHostFragment
as the default nav host. This can be accomplished with this transaction:supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
add a comment |
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = home_nav_fragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_main)
graph.setDefaultArguments(intent.extras)
graph.startDestination = R.id.fragment1
//or
//graph.startDestination = R.id.fragment2
navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph = inflater.inflate(R.navigation.nav_main);
graph.setDefaultArguments(getIntent().getExtras());
graph.setStartDestination(R.id.fragment1);
navHostFragment.getNavController().setGraph(graph);
navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras());
NavigationView navigationView = findViewById(R.id.navigationView);
NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = home_nav_fragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_main)
graph.setDefaultArguments(intent.extras)
graph.startDestination = R.id.fragment1
//or
//graph.startDestination = R.id.fragment2
navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph = inflater.inflate(R.navigation.nav_main);
graph.setDefaultArguments(getIntent().getExtras());
graph.setStartDestination(R.id.fragment1);
navHostFragment.getNavController().setGraph(graph);
navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras());
NavigationView navigationView = findViewById(R.id.navigationView);
NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
edited Jan 22 at 12:19
Maddy
1,66721532
1,66721532
answered Aug 22 '18 at 7:32
Akash PatelAkash Patel
231113
231113
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set thenavHostFragment
as the default nav host. This can be accomplished with this transaction:supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
add a comment |
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set thenavHostFragment
as the default nav host. This can be accomplished with this transaction:supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
2
2
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
First, you need to remove app:navGraph NavHostFragment attribute from your Activity layout xml as NavHostFragment instantiates and sets the navigation graph after host Activity onCreate() call. Also if you use NavigationUI.setupWithNavController method, for example for Toolbar or BottomNavigationView, you need to put this code snippet above NavigationUI.setupWithNavController method call.
– Skyfall100
Aug 29 '18 at 12:12
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set the
navHostFragment
as the default nav host. This can be accomplished with this transaction: supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
I'd also add that to preserve back button behavior in the Kotlin code, you still need a way to set the
navHostFragment
as the default nav host. This can be accomplished with this transaction: supportFragmentManager.beginTransaction().setPrimaryNavigationFragment(navHostFragment).commit()
– Chris
Oct 30 '18 at 15:47
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
the method graph.setDefaultArguments() doesn't exist anymore, you also don't need the last 2 lines (NavigationUI). See my answer for an updated version.
– Danish Khan
Jan 1 at 3:05
add a comment |
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host);
NavController navController = navHost.getNavController();
NavInflater navInflater = navController.getNavInflater();
NavGraph graph = navInflater.inflate(R.navigation.navigation_main);
if (false) {
graph.setStartDestination(R.id.oneFragment);
} else {
graph.setStartDestination(R.id.twoFragment);
}
navController.setGraph(graph);
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<!-- Following line omitted inside <fragment> -->
<!-- app:navGraph="@navigation/navigation_main" -->
<fragment
android:id="@+id/fragment_main_nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<!-- Following line omitted inside <navigation>-->
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main"
>
<fragment
android:id="@+id/oneFragment"
android:name="com.apponymous.apponymous.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one"/>
<fragment
android:id="@+id/twoFragment"
android:name="com.apponymous.apponymous.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two"/>
</navigation>
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, fromtwoFragment
back tooneFragment
, removingtwoFragment
from the back stack? I mean, the Navigation API equivalent ofgetSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to putsetSupportActionBar()
andNavigationUI.setupWithNavController()
? Thanks 😊
– Yan Karin
Feb 5 at 11:15
add a comment |
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host);
NavController navController = navHost.getNavController();
NavInflater navInflater = navController.getNavInflater();
NavGraph graph = navInflater.inflate(R.navigation.navigation_main);
if (false) {
graph.setStartDestination(R.id.oneFragment);
} else {
graph.setStartDestination(R.id.twoFragment);
}
navController.setGraph(graph);
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<!-- Following line omitted inside <fragment> -->
<!-- app:navGraph="@navigation/navigation_main" -->
<fragment
android:id="@+id/fragment_main_nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<!-- Following line omitted inside <navigation>-->
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main"
>
<fragment
android:id="@+id/oneFragment"
android:name="com.apponymous.apponymous.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one"/>
<fragment
android:id="@+id/twoFragment"
android:name="com.apponymous.apponymous.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two"/>
</navigation>
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, fromtwoFragment
back tooneFragment
, removingtwoFragment
from the back stack? I mean, the Navigation API equivalent ofgetSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to putsetSupportActionBar()
andNavigationUI.setupWithNavController()
? Thanks 😊
– Yan Karin
Feb 5 at 11:15
add a comment |
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host);
NavController navController = navHost.getNavController();
NavInflater navInflater = navController.getNavInflater();
NavGraph graph = navInflater.inflate(R.navigation.navigation_main);
if (false) {
graph.setStartDestination(R.id.oneFragment);
} else {
graph.setStartDestination(R.id.twoFragment);
}
navController.setGraph(graph);
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<!-- Following line omitted inside <fragment> -->
<!-- app:navGraph="@navigation/navigation_main" -->
<fragment
android:id="@+id/fragment_main_nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<!-- Following line omitted inside <navigation>-->
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main"
>
<fragment
android:id="@+id/oneFragment"
android:name="com.apponymous.apponymous.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one"/>
<fragment
android:id="@+id/twoFragment"
android:name="com.apponymous.apponymous.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two"/>
</navigation>
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host);
NavController navController = navHost.getNavController();
NavInflater navInflater = navController.getNavInflater();
NavGraph graph = navInflater.inflate(R.navigation.navigation_main);
if (false) {
graph.setStartDestination(R.id.oneFragment);
} else {
graph.setStartDestination(R.id.twoFragment);
}
navController.setGraph(graph);
}
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<!-- Following line omitted inside <fragment> -->
<!-- app:navGraph="@navigation/navigation_main" -->
<fragment
android:id="@+id/fragment_main_nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<!-- Following line omitted inside <navigation>-->
<!-- app:startDestination="@id/oneFragment" -->
<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/navigation_main"
>
<fragment
android:id="@+id/oneFragment"
android:name="com.apponymous.apponymous.OneFragment"
android:label="fragment_one"
tools:layout="@layout/fragment_one"/>
<fragment
android:id="@+id/twoFragment"
android:name="com.apponymous.apponymous.TwoFragment"
android:label="fragment_two"
tools:layout="@layout/fragment_two"/>
</navigation>
answered Jan 1 at 2:46
Danish KhanDanish Khan
5012615
5012615
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, fromtwoFragment
back tooneFragment
, removingtwoFragment
from the back stack? I mean, the Navigation API equivalent ofgetSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to putsetSupportActionBar()
andNavigationUI.setupWithNavController()
? Thanks 😊
– Yan Karin
Feb 5 at 11:15
add a comment |
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, fromtwoFragment
back tooneFragment
, removingtwoFragment
from the back stack? I mean, the Navigation API equivalent ofgetSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to putsetSupportActionBar()
andNavigationUI.setupWithNavController()
? Thanks 😊
– Yan Karin
Feb 5 at 11:15
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
What if this startDestination needs a bundle ?
– Damien Locque
Jan 30 at 14:14
How would I go, then, from
twoFragment
back to oneFragment
, removing twoFragment
from the back stack? I mean, the Navigation API equivalent of getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to put setSupportActionBar()
and NavigationUI.setupWithNavController()
? Thanks 😊– Yan Karin
Feb 5 at 11:15
How would I go, then, from
twoFragment
back to oneFragment
, removing twoFragment
from the back stack? I mean, the Navigation API equivalent of getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new OneFragment()).commit();
? Also, could you show where to put setSupportActionBar()
and NavigationUI.setupWithNavController()
? Thanks 😊– Yan Karin
Feb 5 at 11:15
add a comment |
This can be done with navigation action. Because fragmentA is your start destination, so define an action in fragmentA.
Note these two fields:
app:popUpToInclusive="true" app:popUpTo="@id/fragmentA"
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_a_to_b"
app:destination="@id/fragmentB"
app:popUpToInclusive="true"
app:popUpTo="@id/fragmentA"/>
<fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.mindinventory.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b"/>
</navigation>
When your MainActivity started, just do the navigation with action id, it will remove fragmentA in the stack, and jump to fragmentB. Seemingly, fragmentB is your start destination.
if(!isAllSetUp)
{
// FragmentB
navController.navigate(R.id.action_a_to_b)
}
add a comment |
This can be done with navigation action. Because fragmentA is your start destination, so define an action in fragmentA.
Note these two fields:
app:popUpToInclusive="true" app:popUpTo="@id/fragmentA"
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_a_to_b"
app:destination="@id/fragmentB"
app:popUpToInclusive="true"
app:popUpTo="@id/fragmentA"/>
<fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.mindinventory.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b"/>
</navigation>
When your MainActivity started, just do the navigation with action id, it will remove fragmentA in the stack, and jump to fragmentB. Seemingly, fragmentB is your start destination.
if(!isAllSetUp)
{
// FragmentB
navController.navigate(R.id.action_a_to_b)
}
add a comment |
This can be done with navigation action. Because fragmentA is your start destination, so define an action in fragmentA.
Note these two fields:
app:popUpToInclusive="true" app:popUpTo="@id/fragmentA"
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_a_to_b"
app:destination="@id/fragmentB"
app:popUpToInclusive="true"
app:popUpTo="@id/fragmentA"/>
<fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.mindinventory.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b"/>
</navigation>
When your MainActivity started, just do the navigation with action id, it will remove fragmentA in the stack, and jump to fragmentB. Seemingly, fragmentB is your start destination.
if(!isAllSetUp)
{
// FragmentB
navController.navigate(R.id.action_a_to_b)
}
This can be done with navigation action. Because fragmentA is your start destination, so define an action in fragmentA.
Note these two fields:
app:popUpToInclusive="true" app:popUpTo="@id/fragmentA"
<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/lrf_navigation"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.mindinventory.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_a_to_b"
app:destination="@id/fragmentB"
app:popUpToInclusive="true"
app:popUpTo="@id/fragmentA"/>
<fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.mindinventory.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b"/>
</navigation>
When your MainActivity started, just do the navigation with action id, it will remove fragmentA in the stack, and jump to fragmentB. Seemingly, fragmentB is your start destination.
if(!isAllSetUp)
{
// FragmentB
navController.navigate(R.id.action_a_to_b)
}
edited 23 hours ago
answered Jan 24 at 3:51
LeeLee
8116
8116
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51929290%2fis-it-possible-to-set-startdestination-conditionally-using-android-navigation-ar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
#navigation-architecture-component #navigation-graph
– Akash Patel
Aug 20 '18 at 11:00
check this stackoverflow.com/questions/51173002/…
– Nilesh Rathod
Aug 20 '18 at 11:01
Hi @NileshRathod, It's work if i open FragmentA first then FragmentB. but i want to set StartDestination programmatically. Do you have any solution for same?
– Akash Patel
Aug 20 '18 at 11:16
Try this
NavigationUI.onNavDestinationSelected(menuItem, navController.getNavController());
– Nilesh Rathod
Aug 20 '18 at 11:26
1
I want to do above thing without menu or any other navigation control. maybe there is no way to set startDestination conditionally. so for now I used [stackoverflow.com/questions/51173002/… as per you suggested.
– Akash Patel
Aug 21 '18 at 5:33