Today, let’s create Twitter’s Bottom Navigation Bar with icons that fill in with color when selected.
But first, a bit of background info…
Google’s finally moved away from the Drawer Menu as the primary method of navigation towards something much better in the form of the Bottom Navigation Bar.
Unlike most of Google’s Material Design guidelines, Google actually provides us a Bottom Navigation Bar component for us to use in our apps. Thanks Google…
…or not.
Unfortunately, the default Bottom Navigation Bar Google gives us in the Material Components (com.google.android.material) library is extremely limited and quite unusable in a production app. Plainly put, it is really terrible.
Fortunately, enough apps require a bottom navigation view and the problem is common place enough that there are a plethora of options to choose from when searching for replacement libraries on Github. After trying out most of the available options, I’m happy to say I’ve found the one that works the best. Say hello to…
Here’s what I love about this library:
- Lots of customization options
- Labels/no labels
- Change icon size, or hide icons altogether
- Shifting animation control
- Color/tint control
- Center Floating Action Button
- Viewpager Support
- Fancy Badges!
Last, but perhaps most importantly, this library extends Google’s BottomNavigationView which means it effortlessly integrates with the new JetPack Navigation Architectural component.
Let’s see how we can use this library to replicate Twitter’s bottom bar.
Step 1 / Import Library
Import BottomNavigationViewEx into your project by copying this line into your app’s build.gradle file.
dependencies {
api 'com.github.ittianyu:BottomNavigationViewEx:2.0.2'
}
The library is served by Jitpack so add Jitpack for the library to be found by Gradle.
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
Finally, if you’re using AndroidX, add the following config options to gradle.properties.
android.useAndroidX=true
android.enableJetifier=true
Step 2/ Declare Bottom Menu in XML
Next, let’s layout the bottom bar view in XML. Here, I’m putting the bottom bar in my MainActivity and aligning it at the bottom by wrapping it in a RelativeLayout.
activity_main.xml<RelativeLayout
android:id="@+id/main_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx
android:id="@+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
app:itemIconTint="@color/tab_selector"
app:labelVisibilityMode="unlabeled"
app:menu="@menu/menu_bottom_nav"/>
</RelativeLayout>
Twitter’s bottom bar does not have labels and it looks much cleaner that way. Disable labels by setting the library property labelVisibilityMode
to unlabled
.
Step 3/ Create Bottom Menu Resource
BottomNavigationViewEx extends the Android framework which means we can declare tabs using menu resources. Create a Menu Resource in your res/menu
folder using the following code.
menu_bottom_nav.xml<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/homeFragment"
android:checked="true"
android:icon="@drawable/ic_home_selector"
android:title="@string/home_title"/>
<item
android:id="@+id/momentsFragment"
android:icon="@drawable/ic_search_selector"
android:title="@string/moments_title"/>
<item
android:id="@+id/notificationsFragment"
android:icon="@drawable/ic_notifications_selector"
android:title="@string/notifications_title"/>
<item
android:id="@+id/messagesFragment"
android:icon="@drawable/ic_messages_selector"
android:title="@string/messages_title"/>
</menu>
Step 4/ Import Twitter Colors
To customize our Bottom Navigation View and make it look like Twitter’s, we need to use Twitter’s colors.
First, let’s get Twitter’s bottom tab colors. Twitter used their brand color for the selected tab and dark gray for the unselected state.
colors.xml<color name="twitter_blue">#1da1f2</color>
<color name="deep_gray">#ff657786</color><color name="tab_selected">@color/twitter_blue</color>
Create a color state list selector so the bottom bar can automatically apply the correct color to our tabs based on their selection state.
tab_selector.xml<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/tab_selected" android:state_checked="true" />
<item android:color="@color/deep_gray" android:state_checked="false"/>
</selector>
Step 5/ Import Twitter Icons
It’s pretty difficult to replicate Twitter’s Bottom Bar without Twitter’s icons. Download those icons from this link:
https://www.mediafire.com/folder/2t06cmke9lt7i/Twitter_Bottom_Bar_Icons
One very unique “upgrade” that Twitter made was to use two different versions of their icons in addition to changing the icon color when selected.
In my opinion, this makes the icons more dynamic and is a nice additional microinteraction.
Like with the colors before, we can leverage a drawable selector to automatically switch between icon states.
ic_search_selector.xml<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_search_selected" android:state_checked="true"/>
<item android:drawable="@drawable/ic_search" android:state_checked="false"/>
</selector>
Step 6/ Customize Bottom Bar Programmatically
At this point, the bottom bar is created in XML and appears when we run our app. However, the selected tab’s icon is larger and shifts when the selection changes. Currently, there’s no XML option to disable that shifting so we need to do it programmatically.
Copy the following function into the activity with the bottom bar and call it in onCreate
MainActivityprivate fun initBottomBar() {
bottom_bar.enableItemShiftingMode(false)
bottom_bar.enableAnimation(false)
}
Reload the app via Instant Run and voila!
The next article will cover how to add notification badges to bottom bar tabs. Follow me to be notified :)
Would it help to have access to all the files together in a Git repo? If so, mash that clap button to let me know this article was helpful!