Search code examples
androidandroid-fragmentsbottomnavigationviewandroid-jetpack-navigation

How to manage bottomNavigation from fragment?


I'm trying to set navController to bottomNavigation, but it's requires activity, the problem is my borromNavigation hosted in fragment, so i don't have activity instance.

I've tried

bottom_nav_view.setupWithNavController(findNavController())

and:

val host = Navigation.findNavController(this.activity!!.parent, R.id.my_nav_host_fragment)

bottom_nav_view.setupWithNavController(host)

home_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".ui.fragments.home.HomeFragment">

    <fragment
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@id/bottom_nav_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:id="@+id/my_nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            app:navGraph="@navigation/main_navigation"
            app:defaultNavHost="true"
            />

    <com.google.android.material.bottomnavigation.BottomNavigationView
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:id="@+id/bottom_nav_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:menu="@menu/bottom_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>

So, I need somehow take my_nav_host_fragment from my home_fragment.xml in HomeFragment.kt

HomeFragment.kt

package andy.schedulekpi.ui.fragments.home

import androidx.lifecycle.ViewModelProviders
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupWithNavController

import andy.schedulekpi.R
import andy.schedulekpi.ui.fragments.start.StartFragmentDirections
import kotlinx.android.synthetic.main.home_fragment.*

class HomeFragment : Fragment() {

    companion object {
        fun newInstance() = HomeFragment()
    }

    private lateinit var viewModel: HomeViewModel
    private lateinit var host : NavController

    val safeArgs : HomeFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view =  inflater.inflate(R.layout.home_fragment, container, false)

        //host = Navigation.findNavController(this.activity!!.parent, R.id.my_nav_host_fragment)

        return view
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
        // TODO: Use the ViewModel
        Toast.makeText(this.context, safeArgs.currentWeek.toString(), Toast.LENGTH_SHORT).show()

        //val navController = Navigation.findNavController(activity!!.parent, R.id.my_nav_host_fragment) - don't work

        //val host = Navigation.findNavController()  -ERROR

       // bottom_nav_view.setupWithNavController(findNavController()) -ERROR


    }

}

bottom_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
            android:icon="@drawable/ic_schedule"
            android:id="@+id/scheduleFragment"
            android:title="Schedule"/>

    <item
            android:icon="@drawable/ic_database"
            android:id="@+id/archiveFragment"
            android:title="Database"/>
    <item
            android:id="@+id/teachersFragment"
            android:icon="@drawable/ic_teachers"
            android:title="Teachers"/>

    <item
            android:id="@+id/settingsFragment"
            android:icon="@drawable/ic_settings_"
            android:title="Settings"/>

</menu>

main_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/main_navigation"
            app:startDestination="@id/scheduleFragment">
    <fragment
            android:id="@+id/scheduleFragment"
            android:name="andy.schedulekpi.ui.fragments.schedule.ScheduleFragment"
            android:label="schedule_fragment"
            tools:layout="@layout/schedule_fragment"/>
    <fragment
            android:id="@+id/archiveFragment"
            android:name="andy.schedulekpi.ui.fragments.archive.ArchiveFragment"
            android:label="archive_fragment"
            tools:layout="@layout/archive_fragment"/>
    <fragment
            android:id="@+id/teachersFragment"
            android:name="andy.schedulekpi.ui.fragments.teachers.TeachersFragment"
            android:label="teachers_fragment"
            tools:layout="@layout/teachers_fragment"/>
    <fragment
            android:id="@+id/settingsFragment"
            android:name="andy.schedulekpi.ui.fragments.settings.SettingsFragment"
            android:label="settings_fragment"
            tools:layout="@layout/settings_fragment"/>

</navigation>

I expected to handle bottomNavigation from fragment, but now i clicked on menu items and nothing happend or error.


Solution

  • In HomeFragment to set navController on BottomNavigationView:

    import androidx.navigation.findNavController
    
    Navigation.setViewNavController(bottom_nav_view, activity!!.findNavController(R.id.my_nav_host_fragment))
    

    then when u want get navController from bottom_nav_view:

    bottom_nav_view.findNavController()