Reputation: 711
According to the navigation priciples the first destination in your app should be the screen your users would normally see when they launch the app after signup/login or any other conditional navigation, I called that start destination 'homeFragment'.
Following this principle and after reading the post on conditional navigation by Maria Neumayer I am facing some issues with the Toolbar and the back navigation when going through the conditional navigation flows.
I am architecting the app using one single activity with a ConstraintLayout, a Toolbar and the NavHostFragment:
<android.support.constraint.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=".ui.activities.NavigationTestActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true"
/>
</android.support.constraint.ConstraintLayout>
The main graph looks like this with the home destination as start destination, connected with an action to a detail fragment (this action is triggered from a button) and a conditional navigation implemented using a nested graph:
I called this nested graph welcomeGraph and it includes the screens for login or signup, you can see it here:
In the homeFragment onResume I check if the login/signup has been completed (determined by a dummy boolean stored in sharedPrefs) and if not I launch the welcome nested graph for signup/login.
In the login destination I have a 'Completed' button which sets the dummy boolean in sharedPrefs as true and triggers an action popToWelcomeGraph (inclusive) which should close the whole nested graph and take me back to the homeFragment (this works).
PROBLEM - Toolbar issue in nested graph:
As the Welcome graph is lauched inmediatelly after user lands in the app, the toolbar should not display a back/up arrow in the first destination of that nested graph, instead it should feel as if it was the first screen on the app, and tapping back should quit the app.
QUESTION: Is it possible to alter the Toolbar here to simulate the first screen in the nested graph is the first screen in the app until the login/signup is completed? Would this be a bad practice?
Upvotes: 2
Views: 778
Reputation: 121
I have recently solved this issue by creating an AppBarConfiguration and setting up the toolbar with that configuration. The AppBarConfiguration takes in the top level destination ids as parameter. With that being said, you can do something like
private lateinit var appBarConfiguration: AppBarConfiguration
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
appBarConfiguration = AppBarConfiguration(setOf(R.id.homeFragment,R.id.welcomeFragment))
findViewById<Toolbar>(R.id.toolbar).setupWithNavController(navController, appBarConfiguration)
}
This way the back button won`t be shown on top level fragments.
Upvotes: 3
Reputation: 1034
You have to implement communicator interface like below
interface ActivityCommunicator {
void alterToolbar();
}
and implement it to your activity class like below
class HomeActivity extends AppCompatActivity implements ActivityCommunicator {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Activity code
}
@Override
public void alterToolbar() {
ActionBar actionBar = getSupportActionBar();
// False to hide back button and true to show it
actionBar.setDisplayHomeAsUpEnabled(false);
}
}
and from your fragment you can call it like below
public class MainFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ActivityCommunicator activityCommunicator = (ActivityCommunicator) getActivity();
activityCommunicator.alterToolbar();
// Fragment code
return super.onCreateView(inflater, container, savedInstanceState);
}
}
You can change alterToolbar() implementation as per your need
Upvotes: 1