Customizing Material Navigation Rail in Android
Last Updated :
08 Oct, 2021
In the article, Material Design Component Navigation Rail in Android, it’s been discussed how to implement one of the navigation components that is Navigation Rail especially for the larger screens like desktops or tablets. So in this article, it’s been continued with the customization of the Navigation Rail in android. Have a look at the following image to get an overview of the entire discussion.
Create an empty activity project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.
Add Required Dependency
Include google material design components dependency in the build.gradle file. After adding the dependencies don’t forget to click on the “Sync Now” button present at the top right corner. Note that the Navigation Rail is introduced in the latest release of the material design components version that is 1.4.0 and above.
implementation ‘com.google.android.material:material:1.4.0’
Note that while syncing your project you need to be connected to the network and make sure that you are adding the dependency to the app-level Gradle file as shown below. Note that, the layout is going to remain the same as in the previous article.
Essential Customizations are now discussed one by one
The labels for the icons are optional
There are four modes for labels for each of the icons. Those are:
selected -> The labels are shown only to the selected items on the navigation rail.
labeled -> The labels are shown for all the items.
unlabeled -> All the labels are hidden, even though the item is selected.
auto -> The labels behave as “labelled” when there 3 or less than 3 items and “selected” when there are 4 items or more.
To include these values in XML there is an attribute for the navigation rail that is:
app:labelVisibilityMode=”value”
Have a look at the following example and output:
XML
<? xml version = "1.0" encoding = "utf-8" ?>
< androidx.constraintlayout.widget.ConstraintLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:clipToPadding = "false"
tools:context = ".MainActivity" >
< com.google.android.material.navigationrail.NavigationRailView
android:id = "@+id/navigationRail"
android:layout_width = "wrap_content"
android:layout_height = "match_parent"
android:clipToPadding = "false"
app:headerLayout = "@layout/navigation_rail_fab"
app:labelVisibilityMode = "unlabeled"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent"
app:menu = "@menu/navigation_rail_menu" />
</ androidx.constraintlayout.widget.ConstraintLayout >
|
Output UI:
Adding labels for icons
There is also a badge for items in the Navigation Rail. For example, whenever the new notification or count of the content inside the particular fragment increases, then it can only be informed to the user by increasing the count of the badge or simply a dot badge. Have a look at the following example to get an idea. Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.
XML
<? xml version = "1.0" encoding = "utf-8" ?>
< androidx.constraintlayout.widget.ConstraintLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:clipToPadding = "false"
tools:context = ".MainActivity" >
< com.google.android.material.navigationrail.NavigationRailView
android:id = "@+id/navigationRail"
android:layout_width = "wrap_content"
android:layout_height = "match_parent"
android:clipToPadding = "false"
app:headerLayout = "@layout/navigation_rail_fab"
app:labelVisibilityMode = "labeled"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent"
app:menu = "@menu/navigation_rail_menu" />
</ androidx.constraintlayout.widget.ConstraintLayout >
|
Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.navigationrail.NavigationRailView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super .onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navigationRail: NavigationRailView = findViewById(R.id.navigationRail)
val badge = navigationRail.getOrCreateBadge(R.id.images)
badge.isVisible = true
badge.number = 99
}
}
|
Output UI:
The best practice for adding any badges for the icons is, if there is a need of temporary hiding the badge until the next notification is received, then, in this case, changing the visibility of BadgeDrawable like the following:
Kotlin
val badgeDrawable = navigationRail.getBadge(R.id.images)
if (badgeDrawable != null ) {
badgeDrawable.isVisible = false
badgeDrawable.clearNumber()
}
|
Changing the Elevation of the Navigation Rail container
There is attribute elevation. This attribute only affects the Navigation Rail container. The attribute is:
app:elevation=”value_in_dp”
Have a look at the following example and its output:
XML
<? xml version = "1.0" encoding = "utf-8" ?>
< androidx.constraintlayout.widget.ConstraintLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:clipToPadding = "false"
tools:context = ".MainActivity" >
< com.google.android.material.navigationrail.NavigationRailView
android:id = "@+id/navigationRail"
android:layout_width = "wrap_content"
android:layout_height = "match_parent"
android:clipToPadding = "false"
app:elevation = "18dp"
app:headerLayout = "@layout/navigation_rail_fab"
app:labelVisibilityMode = "labeled"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent"
app:menu = "@menu/navigation_rail_menu" />
</ androidx.constraintlayout.widget.ConstraintLayout >
|
Output UI:
Changing the color of the Navigation Rail container
There is XML attribute for Navigation Rail to change the style or the color of the Navigation Rail that is:
style=”@style/Widget.MaterialComponents.NavigationRailView.Colored.Compact”
Note that, by including this the size of the Navigation Rail becomes compact and it is advised to remove the Floating Action Button removing the header layout attribute in the Navigation Rail. Have a look at the following example to get an idea.
Changing the TextAppearance of the labels
The default text appearance of the labels is Caption in the Material Design Type system so that needs to be overridden with the custom font. So in the themes.xml file invoke the custom style for the Caption type system.
XML
< style name = "TextAppearance.MdcTypographyStyles.Caption" parent = "TextAppearance.MaterialComponents.Caption" >
< item name = "fontFamily" >@font/poppins_regular</ item >
< item name = "android:fontFamily" >@font/poppins_regular</ item >
< item name = "android:textSize" >12sp</ item >
</ style >
|
Now include the TextAppearance.MdcTypographyStyles.Caption in the attributes under the Navigation Rail:
app:itemTextAppearanceActive=”@style/TextAppearance.MdcTypographyStyles.Caption”
app:itemTextAppearanceInactive=”@style/TextAppearance.MdcTypographyStyles.Caption”
Output UI:
Some other Attributes of Navigation Rail Container are:
Element
|
Attribute
|
Related Method
|
Color |
app:backgroundTint |
N/A |
Elevation |
app:elevation |
setElevation |
Some other Attributes of Navigation Rail Items are:
Element
|
Attribute
|
Related Method
|
Menu resource |
app:menu |
inflateMenu
getMenu
|
Ripple (inactive) |
app:itemRippleColor |
setItemRippleColor
getItemRippleColor
|
Ripple (active) |
app:itemRippleColor |
setItemRippleColor
getItemRippleColor
|
Label visibility mode |
app:labelVisibilityMode |
setLabelVisibilityMode
getLabelVisibilityMode
|
Some other Attributes of Navigation Rail Items Icon are:
Element
|
Attribute
|
Related Method
|
Icon |
android:icon |
N/A |
Size |
app:itemIconSize |
setItemIconSize
setItemIconSizeRes
getItemIconSize
|
Color (inactive) |
app:itemIconTint |
setItemIconTintList
getItemIconTintList
|
Color (active) |
app:itemIconTint |
setItemIconTintList
getItemIconTintList
|
Some other Attributes of Navigation Rail Items Text Labels are:
Element
|
Attribute
|
Related Method
|
Text label |
android:title |
N/A |
Color (inactive) |
app:itemTextColor |
setItemTextColor
getItemTextColor
|
Color (active) |
app:itemTextColor |
setItemTextColor
getItemTextColor
|
Typography (inactive) |
app:itemTextAppearanceInactive |
setItemTextAppearanceInactive
getItemTextAppearanceInactive
|
Typography (active) |
app:itemTextAppearanceActive |
setItemTextAppearanceActive
getItemTextAppearanceActive
|
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...