Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace a fragment using NavController.navigate instead of adding it on top

I'm using the "new" Android Jetpack navigation, instead of relying on FragmentManager. I've got a simple main layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activities.MainActivity">

    <FrameLayout
            android:id="@+id/root"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@id/bottomNav">

        <fragment
                android:id="@+id/nav_host_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/navigation_app" />

    </FrameLayout>
    <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:menu="@menu/bottom_menu"
            app:layout_constraintBottom_toBottomOf="@+id/root"/>



</android.support.constraint.ConstraintLayout>

And two additional layouts: "Splashscreen" with a TextView, "Login" with a button. The splashscreen fragment is used as starting point, and has a listener defined as follows:

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        textView.setOnClickListener{
            findNavController(nav_host_fragment).navigate(R.id.action_splashScreenFragment_to_loginFragment)
        }
    }

screenshot

Instead of replacing TextView fragment with Button fragment, the Button fragment is stacked on top.

I've only encountered workarounds such as setting a background color, and clickable parameter, which I consider to be more of a hack, as I believe that the behaviour is exactly the same, but the fragment below is simply hidden. How to properly switch fragments using the NavController?

like image 638
nluk Avatar asked Apr 28 '19 19:04

nluk


People also ask

Is it better to use <fragment> tag for navigation controller?

Personally, from a user perspective, I prefer using <fragment> tag because it uses less code to find the navigation controller. The app also runs perfectly fine with it! Also, the default template project from Android Studio does NOT use <androidx.fragment.app.FragmentContainerView> which it should if that is the recommended way?

How to navigate between fragments using navcontroller in React Native?

After creating the NavController instance we can set Button click for navigation to the second fragment. Navigating between fragments is successful. Let’s add animations to transitions between fragments.

How do I navigate between navhost fragments?

When you navigate between fragments, the destination shown in the NavHost is updated. You'll use a built-in implementation, called NavHostFragment, in your MainActivity. NavController: The NavController object lets you control the navigation between destinations displayed in the NavHost.

Do I need a fragmentmanager when navigating between screens?

If you are navigating between fragment based screens under the same activity, then there is no longer a need for the FragmentManager. Fragment transactions are replaced by providing our navigation graph with actions, destinations and the navigating via the NavController.


1 Answers

Issue seems to have occured because of these two lines:

val host = NavHostFragment.create(R.navigation.navigation_register_login)
supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment,host).setPrimaryNavigationFragment(host).commit()

I guess they shouldn't be called, and all basic requirements are fulfilled by this line in layout:

android:name="androidx.navigation.fragment.NavHostFragment"
like image 111
nluk Avatar answered Nov 15 '22 08:11

nluk