SumOn
SumOn

Reputation: 336

BottomNavigationBar not working properly after navigate to navigation fragment by cutom button click

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

        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>

Upvotes: 4

Views: 1849

Answers (4)

bhanwar
bhanwar

Reputation: 51

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
    }
}

Upvotes: 2

pbl9
pbl9

Reputation: 111

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.

Upvotes: 1

DHAVAL A.
DHAVAL A.

Reputation: 2321

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()
)

Upvotes: 2

Sohaib Ahmed
Sohaib Ahmed

Reputation: 3062

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)

Upvotes: -1

Related Questions