Bottom Navigation in Android Application with Activities — Material Design

Srinivasa Rao Makkena
4 min readNov 11, 2019

--

In iOS, there is view called TabViewController, which is to display the menu items and to easily navigate between menu items like Home, Profile, Notifications, Settings etc. As part of the material design concept, there is a view called “BottomNavigationView” in Android as well. Mostly, we will have to work with a hamburger menu available in android. But, some times we may need to design as in iOS tab view. Then it will be very easy to implement using this Material Design concept.

It’s easy to implement this with Fragments with single layer in each tab(Single screen, no extended flow) as compared with Activities but there are many advantages with activities.

For example, In the above image, we have a list of items developed using ExpandableListView. When user clicked on one item, it will open another screen with another list. And the flow continues to more screens, lets say more than 5. If you implement this kind of app with single activity and all fragments. Its not easy to maintain the fragments and their navigation. If we implement separate activity for each tab and then we can use fragments for the continuous flow in each tab. Many people asked me to implement this architecture. So, I thought of writing an article with proper implementation.

https://gfycat.com/spottedidiotichypsilophodon-simon-pegg-all-right-annoyed-spaced

Let’s talk about the code.

As part of the Material Design Concept, we need to use the below Gradle dependency.

Steps

1. implementation 'com.android.support:design:28.0.0-alpha1'

2. item_bottom_navigation.xml

The below view is available from the above mentioned support library.

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.bottomnavigation.BottomNavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_menu"
/>

Suppose if we have 4 tabs, we can create 4 activities for these 4 tabs.

We need to include the bottom navigation view in all the layouts using <include/> tag to avoid overdraw.

For example,

3. activity_home.xml

Here “item_bottom_navigation” aligns bottom to the screen with the help of “app:layout_constraintBottom_toBottomOf=”parent”” in constraint layout. Depends on the layout we use, we need to arrange that view in screen.

<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
>

<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/more"
/>

<include
layout="@layout/item_bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

4. We need menu items to display with icons.

bottom_menu.xml :

We need to create new resource folder with type menu by following the steps as below. Right click on res folder -> New ->Android Resource File -> Select resource type as Menu and name it as you wish.(In this project, I named it as bottom_menu.xml)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="@+id/action_home"
android:enabled="true"
android:icon="@drawable/home"
android:title="@string/home"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/action_profile"
android:enabled="true"
android:icon="@drawable/profile"
android:title="@string/profile"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/action_notification"
android:enabled="true"
android:icon="@drawable/notification"
android:title="@string/notifications"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/action_more"
android:enabled="true"
android:icon="@drawable/ic_more"
android:title="@string/more"
app:showAsAction="ifRoom"
/>
</menu>

Finally, we need java/ Kotlin classes to call this views from.

5. Create the abstract BaseActivity.java and use this as Super class in all the other activity classes. And implements with interface “BottomNavigationView.OnNavigationItemSelectedListener”.

abstract class means “ we can have the class with unimplemented methods”

public abstract class BaseActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {

protected BottomNavigationView navigationView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());

navigationView = (BottomNavigationView) findViewById(R.id.navigation);
navigationView.setOnNavigationItemSelectedListener(this);
}

@Override
protected void onStart() {
super.onStart();
updateNavigationBarState();
}

// Remove inter-activity transition to avoid screen tossing on tapping bottom navigation items
@Override
public void onPause() {
super.onPause();
overridePendingTransition(0, 0);
}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
navigationView.postDelayed(() -> {
int itemId = item.getItemId();
if (itemId == R.id.action_home) {
startActivity(new Intent(this, HomeActivity.class));
} else if (itemId == R.id.action_profile) {
startActivity(new Intent(this, ProfielActivity.class));
} else if (itemId == R.id.action_notification) {
startActivity(new Intent(this, NotificationsActivity.class));
} else if (itemId == R.id.action_more) {
startActivity(new Intent(this, MoreActivity.class));
}
finish();
}, 300);
return true;
}

private void updateNavigationBarState() {
int actionId = getNavigationMenuItemId();
selectBottomNavigationBarItem(actionId);
}

void selectBottomNavigationBarItem(int itemId) {
MenuItem item = navigationView.getMenu().findItem(itemId);
item.setChecked(true);
}

abstract int getLayoutId(); // this is to return which layout(activity) needs to display when clicked on tabs.

abstract int
getBottomNavigationMenuItemId();//Which menu item selected and change the state of that menu item
}

For example, we need to use this class for all the tab activities if you want to show the Navigation view in that screen.

public class HomeActivity extends BaseActivity {


@Override
int getLayoutId() {
return R.layout.activity_home;
}

@Override
int getBottomNavigationMenuItemId() {
return R.id.action_home;
}
}
https://giphy.com/explore/thats-it

References:

https://developer.android.com/reference/android/support/design/widget/BottomNavigationView

--

--