2

Take a Bottom Navigation activity from android studio template. there are 3 fragment with 3 item in BottomNavBar (HomeFragment, DashboardFragment, NotificationsFragment) navigate to DashboardFragment from HomeFragment by a button click. after that home item click from BottomNavBar should open Homefragment. But not working as expected.

HomeFramgent after navigate to dashborad gif

  • Go to DashboardFrament from HomeFrament by
        textView.setOnClickListener {
            findNavController().navigate(R.id.navigation_dashboard)
        }

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    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)

        navView.setupWithNavController(navController)
    }
}

main_activity.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"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment_activity_main"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

HomeFramgent.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val textView: TextView = view.findViewById(R.id.text_home)
        textView.setOnClickListener {
            findNavController().navigate(R.id.navigation_dashboard)
        }
    }

navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<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/mobile_navigation"
    app:startDestination="@+id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.app.bottomnav.ui.home.HomeFragment"
        android:label="@string/title_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/navigation_dashboard"
        android:name="com.app.bottomnav.ui.dashboard.DashboardFragment"
        android:label="@string/title_dashboard"
        tools:layout="@layout/fragment_dashboard" />

    <fragment
        android:id="@+id/navigation_notifications"
        android:name="com.app.bottomnav.ui.notifications.NotificationsFragment"
        android:label="@string/title_notifications"
        tools:layout="@layout/fragment_notifications" />
</navigation>
SumOn
  • 306
  • 1
  • 4

4 Answers4

1

Whenever you are navigating to any root destination from another fragment, you should have to clear the previous stack using popUpTo option builder.

Update your code navigation code in your home fragment.

findNavController()
    .navigate(R.id.navigation_dashboard,
            null,
            NavOptions.Builder()
               .setPopUpTo(R.id.navigation_home, true)
               .build()
)
DHAVAL A.
  • 2,251
  • 2
  • 12
  • 27
  • then how to handle back pressed? app suppose to close from home fragment which is default behavior. not from dashboard. should I override onBackPressed() ??? – SumOn Jan 16 '23 at 11:25
  • I think you can not manage both at the same time. Navigation component doesn't support manual navigation to the root fragments yet. So yes, you have to override back pressed. – DHAVAL A. Jan 16 '23 at 11:32
1

I don't know what is the best solution for that problem but here is a workaround: In your activity you add public method:

fun navigateToNavBarDestination(destinationId: Int) {
    binding.navView.setSelectedItemId(destinationId)
}

And in your fragments referenced in BottomNavigationView instead calling NavController::navigate you navigate in that way, lets say to dashboard:

fun navigateToDashboard() {
(activity as? MainActivity)?.navigateToNavBarDestination(R.id.dashboard)
}

Its not the perfect solution but works.

pbl9
  • 91
  • 3
1

HomeFragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val textView: TextView = view.findViewById(R.id.text_home)
    textView.setOnClickListener {
       /**
       * replace this line
       */
       // findNavController().navigate(R.id.navigation_dashboard)
       val mainActivity = (requiredActivity() as MainActivity)
       mainActivity.binding.navView.selectedItemId = R.id.navigation_dashboard
    }
}
bhanwar
  • 41
  • 1
  • 7
0

Add these lines in your MainActivity onCreate.

val appBarConfiguration = AppBarConfiguration(
    setOf(
        R.id.navigation_home,
        R.id.navigation_dashboard,
        R.id.navigation_notifications
    ))

setupActionBarWithNavController(navController, appBarConfiguration)
Sohaib Ahmed
  • 1,990
  • 1
  • 5
  • 23