How to highlight the item when pressed using BottomNavigationView between activities? How to highlight the item when pressed using BottomNavigationView between activities? android android

How to highlight the item when pressed using BottomNavigationView between activities?


You can use BottomNavigationView with activities representing tabs. The key is to repeat the navigation view component in each activity, and have the code of each activity control the navigation component: starting the right activity on navigation item clicks and selecting a proper navigation item after the activity has started.

You need to start newly selected activities (tabs) with a delay as to allow the tab switching animation to complete before the new activity replaces the previous one.

My approach was to have all activities representing tabs inherit from the same BaseActivity class implementing the common behavior.

This is the code of an example BaseActivity:

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.navigation_home) {                startActivity(new Intent(this, HomeActivity.class));            } else if (itemId == R.id.navigation_dashboard) {                    startActivity(new Intent(this, DashboardActivity.class));            } else if (itemId == R.id.navigation_notifications) {                    startActivity(new Intent(this, NotificationsActivity.class));            }            finish();        }, 300);        return true;    }    private void updateNavigationBarState(){        int actionId = getNavigationMenuItemId();        selectBottomNavigationBarItem(actionId);    }    void selectBottomNavigationBarItem(int itemId) {        Menu menu = navigationView.getMenu();        for (int i = 0, size = menu.size(); i < size; i++) {            MenuItem item = menu.getItem(i);            boolean shouldBeChecked = item.getItemId() == itemId;            if (shouldBeChecked) {                item.setChecked(true);                break;            }        }    }    abstract int getContentViewId();    abstract int getNavigationMenuItemId();}

This is my whole example based on the Android Studio's Bottom Navigation Activity template:

https://github.com/ddekanski/BottomNavigationViewBetweenActivities


To anyone still looking for this, @javazian's answer of extending each activity is real overkill in my opinion.

A much more succinct solution is to retrieve the nav menu and manually check the relevant menu item.

Note in the example below, INSERT_INDEX_HERE needs to be replaced with the index of the menu item, (e.g. the menu item on the far left would have index 0).

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_connections);    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);    // Ensure correct menu item is selected (where the magic happens)    Menu menu = navigation.getMenu();    MenuItem menuItem = menu.getItem(INSERT_INDEX_HERE);    menuItem.setChecked(true);}


You absolutely can use BottomNavigationView with activities, but it's not recommended. Better is to use it with Fragments, main benefits are:

  • Animation in BottomNavigationView (without ugly delay in case of Activities)
  • Maintain state of Fragments easily
  • Flexible backstack

But if you want to stick with Activities, then @javaxian answer is very good, but we can improve it:

  1. If our layout file doesn't have a BottomNavigation with proper id, then we will have exception. Better is to have common layout file for activities with navigation.

Solution:

1) Rename BaseActivity to BaseNavigationActivity

2) Make single layout file for all your Activities (for example activity_navigation.xml), and explicitly call in BaseNavigationActivity setContentView(R.layout.activity_navigation);

3) Remove abstract int getContentViewId();

  1. Code in selectBottomNavigationBarItem(int itemId) is overhead, we can do it much more simplier

Solution (in Kotlin):

private fun selectBottomNavigationBarItem(itemId: Int) {    val menuItem = navigationView.menu.findItem(itemId)    menuItem.isChecked = true}