abstract class BaseBottomNavActivity extends BaseActivity { // you can directly extend AppCompatActivity @Override @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initOnCreate(savedInstanceState); getBottomNavigationBar().setOnTabSelectionListener( new CustomBottomNavigationBar.OnTabSelectionListener() { @Override public void onTabSelected(int position) { // start your various top-level activites from here if (position != getCurrentBottomNavPosition()) { switch (position) { case CustomBottomNavigationBar.POSITION_HOME_TAB: HomeActivity.start(BaseBottomNavActivity.this); break; case CustomBottomNavigationBar.POSITION_UPDATES_TAB: UpdatesActivity.start(BaseBottomNavActivity.this); break; case CustomBottomNavigationBar.POSITION_BOOKMARKS_TAB: BookmarksActivity.start(BaseBottomNavActivity.this); break; case CustomBottomNavigationBar.POSITION_PROFILE_TAB: ProfileActivity.start(BaseBottomNavActivity.this); break; case CustomBottomNavigationBar.POSITION_FINISHED_STORIES_TAB: FinishedStoriesActivity.start(BaseBottomNavActivity.this); break; } } else { onNavBarReselect(); } } }); } protected abstract void onNavBarReselect(); // child activity should implement how re-selecting the same (current) tab will be handled. @Override protected void onResume() { super.onResume(); getBottomNavigationBar().setSelectedTab(getCurrentBottomNavPosition()); } // TODO: uncomment if backstack behavior needs to change // @Override // public void onBackPressed() { // ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); // List appTasks = activityManager.getAppTasks(); // for (ActivityManager.AppTask task : appTasks) { // task.finishAndRemoveTask(); // } // } protected abstract int getCurrentBottomNavPosition(); // e.g. for the switch case above HomeActivity returns CustomBottomNavigationBar.POSITION_HOME_TAB here protected abstract CustomBottomNavigationBar getBottomNavigationBar(); //e.g. get the bottom nav bar from the child's layout protected abstract void initOnCreate(Bundle savedInstanceState); //e.g. child activities to call this, initialize layout in this so that bottom nav bar is available when line 8 is called @NonNull protected Snackbar showSnackbar(Snackbar snackbar, boolean hasAction) { // used to show the snackbar above the bottom nav bar. This assumes that the parent of each child activity is a coordinator layout. Typeface font = Typeface.createFromAsset(getAssets(), AppTextView.APP_TEXT_FONT); TextView tv = (TextView) (snackbar.getView()).findViewById(android.support.design.R.id.snackbar_text); tv.setTypeface(font); Button button = (Button) (snackbar.getView()).findViewById(android.support.design.R.id.snackbar_action); button.setTypeface(font); CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) snackbar.getView().getLayoutParams(); params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, getBottomNavigationBar().getBottomBarHeight()); snackbar.getView().setLayoutParams(params); snackbar.show(); return snackbar; } }