Search code examples
androidandroid-fragmentskotlinandroid-navigationandroid-bottomnav

Hide Bottom Navigation View in fragment


I want to hide bottomNavigationView in some fragments.

I have tried the below code, but it has a flicker effect. (bottomNavigationView hide before the nextFragment becomes visible.

    val navController = this.findNavController(R.id.nav_host_home)
    navController.addOnDestinationChangedListener { _, destination, _ ->
    when (destination.id) {
        R.id.searchArticlesFragment -> bnvMain.visibility = View.GONE
        R.id.articleFragment -> bnvMain.visibility = View.GONE
            else -> bnvMain.visibility = View.VISIBLE
        }
    }

I have also tried another code. But it resizes the fragment. And giving OutOfMemoryException in Destination Fragment.

    supportFragmentManager.registerFragmentLifecycleCallbacks(object :
        FragmentManager.FragmentLifecycleCallbacks() {
        override fun onFragmentViewCreated(
            fm: FragmentManager,
            f: Fragment,
            v: View,
            savedInstanceState: Bundle?
        ) {
            when (f) {
                is SearchArticlesFragment -> bnvMain.visibility = View.GONE
                is ArticleDetailsFragment -> bnvMain.visibility = View.GONE
                else -> bnvMain.visibility = View.VISIBLE
            }
        }
    }, true)

Please help me how can I hide the bottomNavigationView in the proper and best possible way? Is this the only way I can hide the bottomNavigationView? How youtube and Instagram achieve this behavior?


Solution

  • If your code follows single activity design pattern then the following solution suites you.

    1. Create a method inside the parent activity to hide/show bottomNavigationView.
    2. Create a BaseFragment class(create your fragments by extending this BaseFragment Class)
    3. In the BaseFragment create a variable to hold the bottomNavigationViewVisibility (hide/show)
    4. In onActivityCreated method of the BaseFragment, get the activity reference and set the bottomNavigationViewVisibility by calling the method which we created in STEP1.
    5. In each fragment you create, just set the bottomNavigationViewVisibility variable.

    Example: In parentAcitivty layout, file add bottomNavigationView

            <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/main_bottom_navigation_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?android:attr/windowBackground"
                app:labelVisibilityMode="labeled"
                app:menu="@menu/main_nav" />
    

    Step 1: In parent activity, create a method to change the visibility.

     fun setBottomNavigationVisibility(visibility: Int) {
            // get the reference of the bottomNavigationView and set the visibility.
            activityMainBinding.mainBottomNavigationView.visibility = visibility
        }
    

    Step 2 & 3 & 4:

        abstract class BaseFragment : Fragment() {
        
            protected open var bottomNavigationViewVisibility = View.VISIBLE
        
            override fun onActivityCreated(savedInstanceState: Bundle?) {
                super.onActivityCreated(savedInstanceState)
                // get the reference of the parent activity and call the setBottomNavigationVisibility method.
                if (activity is MainActivity) {
                   var  mainActivity = activity as MainActivity
                    mainActivity.setBottomNavigationVisibility(bottomNavigationViewVisibility)
                }
            }
     override fun onResume() {
            super.onResume()
            if (activity is MainActivity) {
                mainActivity.setBottomNavigationVisibility(bottomNavigationViewVisibility)
            }
        }
        }
    

    Step 5:

    class SampleFragment1 : BaseFragment() {
    
        // set the visibility here, it takes care of setting the bottomNavigationView.
        override var navigationVisibility = View.VISIBLE
        
       // override var navigationVisibility = View.GONE
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_sampleFragment1, container, false)
        }
    }