Search code examples
androidandroid-architecture-navigation

Navigation Component: Toolbar issue in conditional navigation


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:

Main Graph

I called this nested graph welcomeGraph and it includes the screens for login or signup, you can see it here:

Welcome Nested Graph

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?


Solution

  • 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