Android navigation drawer bottom navigation :
This tutorial is being presented as from request from user i am going to explain the usage of both android navigation drawer and bottom navigation in a single activity.
Generally we use android navigation drawer and bottom navigation separately but now we will try to join them.
Android navigation drawer
[/et_pb_text][et_pb_text admin_label=”Text” background_layout=”light” text_orientation=”left” use_border_color=”off” border_color=”#ffffff” border_style=”solid”]
Project Structure :
Project structure depicting the flow of the files used in the project for android navigation drawer bottom navigation
mobile_navigation.xml
Add navigation’s in navigation folder so that we can easily navigate in between fragments it’s again a optional process.
If you are not familiar with this declarations you may follow the traditional way of navigation using fragment managers.
<?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/nav_home"> <fragment android:id="@+id/nav_home" android:name="com.abhishek.navigationdrawerwithbottom.ui.home.HomeFragment" android:label="@string/menu_home" tools:layout="@layout/fragment_home"> <action android:id="@+id/action_HomeFragment_to_HomeSecondFragment" app:destination="@id/nav_home" /> </fragment> <fragment android:id="@+id/nav_gallery" android:name="com.abhishek.navigationdrawerwithbottom.ui.gallery.GalleryFragment" android:label="@string/menu_gallery" tools:layout="@layout/fragment_gallery" /> <fragment android:id="@+id/nav_slideshow" android:name="com.abhishek.navigationdrawerwithbottom.ui.slideshow.SlideshowFragment" android:label="@string/menu_slideshow" tools:layout="@layout/fragment_slideshow" /> <fragment android:id="@+id/nav_dashboard" android:name="com.abhishek.navigationdrawerwithbottom.ui.dashboard.DashboardFragment" android:label="@string/menu_dashboard" tools:layout="@layout/fragment_dashboard" /> <fragment android:id="@+id/nav_notifications" android:name="com.abhishek.navigationdrawerwithbottom.ui.notifications.NotificationsFragment" android:label="@string/menu_notifications" tools:layout="@layout/fragment_notifications" /> </navigation>
content_main.xml
Add a host fragment and Bottom Navigation View to the screen and adjust them according to your requirements so as to make a clean code.
<?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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/app_bar_main"> <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:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/mobile_navigation" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/windowBackground" app:labelVisibilityMode="labeled" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/activity_main_drawer" /> </androidx.constraintlayout.widget.ConstraintLayout>
app_bar_main.xml
Add toolbar to app_bar_main layout and also include content_main in the app bar
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </com.google.android.material.appbar.AppBarLayout> <include layout="@layout/content_main" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
nav_header_main.xml
Here in this block we will find the header details like user name, user image and other user related details after the login.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="@dimen/nav_header_height" android:background="@drawable/side_nav_bar" android:gravity="bottom" android:orientation="vertical" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/nav_header_desc" android:paddingTop="@dimen/nav_header_vertical_spacing" app:srcCompat="@mipmap/ic_launcher_round" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" android:text="@string/nav_header_title" android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/nav_header_subtitle" /> </LinearLayout>
activity_main_drawer.xml
Add items these will be show in both the android navigation drawer and bottom navigation’s.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_home" android:icon="@drawable/ic_menu_camera" android:title="@string/menu_home" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="@string/menu_gallery" /> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="@string/menu_slideshow" /> <item android:id="@+id/nav_dashboard" android:icon="@drawable/ic_dashboard_black_24dp" android:title="@string/menu_dashboard" /> <item android:id="@+id/nav_notifications" android:icon="@drawable/ic_notifications_black_24dp" android:title="@string/menu_notifications" /> </group> </menu>
activity_main.xml
In the drawer layout specify the main layout through include and also navigation drawer
<?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> </androidx.drawerlayout.widget.DrawerLayout>
Now we will implement fragments
fragment_home.xml
We are considering a single textview to show the fragment name so that user can know in which fragment is loaded currently.
<?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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.home.HomeFragment"> <TextView android:id="@+id/text_home" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:textAlignment="center" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
HomeViewModel.class
Add a view model with mutable live data.This is a part of MVVM architectural way if you want to skip may directly set the value of textview in the activity itself.
package com.abhishek.navigationdrawerwithbottom.ui.home import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class HomeViewModel : ViewModel() { private val _text = MutableLiveData<String>().apply { value = "This is home Fragment" } val text: LiveData<String> = _text }
HomeFragment.class
Initialize a HomeViewModel with lateinit observe the data from view model and set it to textview.
package com.abhishek.navigationdrawerwithbottom.ui.home import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.abhishek.navigationdrawerwithbottom.R class HomeFragment : Fragment() { private lateinit var homeViewModel: HomeViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java) val root = inflater.inflate(R.layout.fragment_home, container, false) val textView: TextView = root.findViewById(R.id.text_home) homeViewModel.text.observe(viewLifecycleOwner, Observer { textView.text = it }) return root } }
MainActivity.java
Enable drawer layout and bottom navigation’s in the main activity and configure them with the controller.
Drawer layout
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
Navigation View
val navView: NavigationView = findViewById(R.id.nav_view)
BottomNavigationView
val navBottomView : BottomNavigationView = findViewById(R.id.bottom_navigation_view)
Create a controller
val navController = findNavController(R.id.nav_host_fragment)
add fragments to configurations to navigate
appBarConfiguration = AppBarConfiguration(setOf( R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,R.id.nav_dashboard,R.id.nav_notifications), drawerLayout) setupActionBarWithNavController(navController, appBarConfiguration)
finally setup both the navigation’s
navView.setupWithNavController(navController) navBottomView.setupWithNavController(navController)
import android.os.Bundle import android.view.Menu import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.snackbar.Snackbar import com.google.android.material.navigation.NavigationView import androidx.navigation.findNavController import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.navigateUp import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import androidx.drawerlayout.widget.DrawerLayout import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import com.google.android.material.bottomnavigation.BottomNavigationView class MainActivity : AppCompatActivity() { private lateinit var appBarConfiguration: AppBarConfiguration override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val toolbar: Toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) val navView: NavigationView = findViewById(R.id.nav_view) val navBottomView : BottomNavigationView = findViewById(R.id.bottom_navigation_view) val navController = findNavController(R.id.nav_host_fragment) // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. appBarConfiguration = AppBarConfiguration(setOf( R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,R.id.nav_dashboard,R.id.nav_notifications), drawerLayout) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) navBottomView.setupWithNavController(navController) } override fun onCreateOptionsMenu(menu: Menu): Boolean { // Inflate the menu; this adds items to the action bar if it is present. menuInflater.inflate(R.menu.main, menu) return true } override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment) return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() } }
For second part of the tutorial android navigation drawer bottom navigation with remaining fragments code may visit
https://androidcoding.in/2020/05/21/android-bottom-navigation-and-navigation-drawer-part-2/