BottomNavigationView - How to get selected menu item? - android

I used BottomNavigationView to switch fragments. How to get currently selected menu item, to prevent reopening fragment ?
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
return false;
}
});
}

Get selected item at first and then getMenu().findItem(int itemId)
bottomNavigationView.getMenu().findItem(bottomNavigationView.getSelectedItemId())

Solution:
private int getSelectedItem(BottomNavigationView bottomNavigationView) {
Menu menu = bottomNavigationView.getMenu();
for (int i = 0; i < bottomNavigationView.getMenu().size(); i++) {
MenuItem menuItem = menu.getItem(i);
if (menuItem.isChecked()) {
return menuItem.getItemId();
}
}
return 0;
}

Get the currently selected menu item ID using getSelectedItemId:
int selectedItemId = bottomNavigationView.getSelectedItemId();
MenuItem selectedItem = bottomNavigationView.getMenu().findItem(selectedItemId);
This method started being available from Android Support Library 25.3.0.

I think the simplest solution for checking if the previous item is the next item is this:
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
final int previousItem = bottomNavigationView.getSelectedItemId();
final int nextItem = item.getItemId();
if (previousItem != nextItem) {
switch (nextItem) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
}
return true;
}
}
);
Note that there is no need for iterating, and that onNavigationItemSelected returns true, because the function consumes the event.
I hope it helps someone.

Related

Show bottom navigation bar inside a fragment

I want to show Bottom Navigation View inside a fragment just like Instagram. First of all is it possible to add bottom navigation view inside fragment? And if yes, then how?
This is inside onCreateView:
private BottomNavigationView.OnNavigationItemSelectedListener
mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment fragment;
switch (menuItem.getItemId()){
case R.id.navigation_home:
toolbar.setTitle("Home");
return true;
case R.id.navigation_attend:
toolbar.setTitle("Attendance");
return true;
case R.id.navigation_inquire:
toolbar.setTitle("Inquiry");
return true;
case R.id.navigation_help:
toolbar.setTitle("Help Desk");
return true;
case R.id.navigation_setting:
toolbar.setTitle("Profile");
return true;
}
return false;
}
};
And according to https://www.androidhive.info/2017/12/android-working-with-bottom-navigation/ we've to use:
ActionBar toolbar = getSupportActionBar();
toolbar.setTitle("Home");
But I know this isn't working...
Thanks in advance

How to highlight the corresponding fragment item icon in BottomNavigationView while clicking on backpress?

I am having a BottomNavigationView with 3 item tabs at the bottom of the screen.Each of the item tabs has two fragments in it. I am clicking on this flow, Item1Fragment -> Item2Fragment -> Item3Fragment-> SubItem3Fragment1 -> SubItem3Fragment2. So when I backpress from Item3Fragment ,Item2Fragment and Item1Fragment's coresponding item icons are highlighted.
I am referring this post Change BottomNavigationView Icons on Back Button clicked
What I need is when i backpress from Item3Fragment the flow should be SubItem3Fragment1(3rd Item icon Highlighted) -> Item3Fragment (3rd Item icon Highlighted)-> Item2Fragment (2nd Item icon Highlighted)->Item1Fragment (1st Item icon Highlighted)
I am calling the SubItemFragments with
transaction.addToBackStack("subfrag");
Deque<Integer> mStack = new ArrayDeque<>();
boolean isBackPressed = false;
private void setBottomNavigationView() {
mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_home:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_home);
}
isBackPressed = false
setFragment(HomeFragment.newInstance(), HOME_FRAGMENT);
return true;
case R.id.ic_search:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_search);
}
isBackPressed = false
setFragment(SearchFragment.newInstance(), SEARCH_FRAGMENT);
return true;
case R.id.ic_circle:
if(!isBackPressed) {
pushFragmentIntoStack(R.id.ic_circle);
}
isBackPressed = false
setFragment(ShareFragment.newInstance(), SHARE_FRAGMENT);
return true;
default:
return false;
}
}
});
mBottomNavigationView.setOnNavigationItemReselectedListener(new
BottomNavigationView.OnNavigationItemReselectedListener() {
#Override
public void onNavigationItemReselected(#NonNull MenuItem item) {
}
});
mBottomNavigationView.setSelectedItemId(R.id.ic_home);
pushFragmentIntoStack(R.id.ic_home);
}
private void pushFragmentIntoStack(int id)
{
if(mStack.size() < 3)
{
mStack.push(id);
}
else
{
mStack.removeLast();
mStack.push(id);
}
}
private void setFragment(Fragment fragment, String tag) {
FragmentTransaction transaction = mFragmentManager.beginTransaction();
transaction.replace(R.id.container, fragment, tag);
transaction.commit();
}
#Override
public void onBackPressed() {
if(mStack.size() > 1)
{
isBackPressed = true;
mStack.pop();
mBottomNavigationView.setSelectedItemId(mStack.peek());
}
else
{
super.onBackPressed();
}
}
I fixed this case by getting the fragment name, using the fragment name I am assigning the id for tabItem.Then using the tabItem id
Menu menu = bottomNavigationView.getMenu();
MenuItem menuItem = menu.getItem(tabId);
menuItem.setChecked(true);

android change default item in bottom bar

I use bottom bar in my application .but I want to change default item(tab) in bottom bar.I do not use any external library.just how I can set my favorite tab when application runs.
My codes:
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_home:
selectedFragment = Fragment1.newInstance();
break;
case R.id.action_product:
selectedFragment = Fragment2.newInstance();
break;
case R.id.action_order:
selectedFragment = Fragment3.newInstance();
break;
case R.id.action_contact:
selectedFragment = Fragment4.newInstance();
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.scrollView, selectedFragment);
transaction.commit();
return true;
}
});
This should work (I use it with api 19+)
bottomNavigationView.getMenu().getItem(index).setChecked(true);
bottomNavigationView.setSelectedItemId(R.id.action_home);
This will work
for (int i = 0, size = menu.size(); i < size; i++) {
MenuItem item = menu.getItem(i);
item.setChecked(item.getItemId() == 0);
}
If you want a specific item to be opened when the app is started. Just try this code:
bottomNavigationView.setSelectedItemId(R.id.your_id);
But it is for API 25 and higher only.

Get selected menu item's index value in the navigation drawer

I have implemented navigation drawer, it is working fine. The only problem that I have to make selected item to deselect when the navigationdrawer closes. I wonder how could I able to get the index value of selected menu item.
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(false);
}
)}
One way to do is store menu item ID in variable e.g checkedItemID
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItemID=menuItem.getItemId();
}
)}
Then on implement
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
// Do whatever you want here
navigationView.getMenu().findItem(menuItemID).setChecked(false);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// Do whatever you want here
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
Make a variable position of int datatype. Firstly set its value to 0 and onNavigationItemSelected change its value to menuItem index(like 0 or 1 or 2 and so on).Now this position will provide you the index of selected menuItem.
int position = 0;
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.first:
position = 0;
break;
case R.id.second:
position = 1;
break;
case R.id.third:
position = 2;
break;
}
return true;
}
});
Try this to get navigation item at position 0 getItem(index) will give you desired item
navigationView.getMenu().getItem(selectedposition).setChecked(false);
also use this link for reference for getting seleted item http://thegeekyland.blogspot.in/2015/11/navigation-drawer-how-set-selected-item.html
use below code for getting selected position
int selectedposition= 0;
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.firstitemid:
selectedposition= 0;
break;
case R.id.seconditemid:
selectedposition= 1;
break;
case R.id.thirditemid:
selectedposition= 2;
break;
}
return true;
}
});
Another easy way that worked for me
public boolean onNavigationItemSelected(MenuItem item) {
int index = (item.getItemId() % item.getGroupId())-1;
....
}
I think, this would be much more efficient than using For loop or Switch case.
If you still have problems then my suggestion would be to check your Item Id and group Id in Log-cat so that you would have a better understanding of what you are dealing with.
This is all you need, it deselects and selects the new one
navigationView.setCheckedItem(item.getItemId());
And it should go at the bottom of onNavigationItemSelected.
To make it more clear here's an example
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
controller.setFragment(new HomeFragment());
break;
case R.id.nav_settings:
controller.setFragment(new SettingsFragment());
break;
case R.id.nav_logout:
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.putExtra(autoLogin, false);
startActivity(intent);
break;
}
navigationView.setCheckedItem(item.getItemId());
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return false;
}
First assign your navigationMenu to a class field
private NavigationView navigationView;
private int currentPosition;
...
navigationView = (NavigationView) findViewById(R.id.nav_view);
Now in the menu callback you can loop over the menu items :
public boolean onNavigationItemSelected(MenuItem item) {
for (int i=0;i<navigationView.getMenu().size();i++){
if(item==navigationView.getMenu().getItem(i)){
currentPosition=i;
break;
}
}
....
}
You can change the order of the menu items without breaking anything

How to get MenuItem position in the listener using the new NavigationView

The topic says it all. How should I go about retrieving the item position on the onClick listener using NavigationView? Also, why is there no getHeader method? Lastly I am doing everything programmatically, but the header is still clickable. Any thoughts?
Thanks!
I found a simple solution. You can assign an order using Menu's add(...) method. Then you can retrieve the order using MenuItems's getOrder(...) method. If you are using xml, you can use android:orderInCategory="...".
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);.
Menu menu = navigationView.getMenu();
for(int i=0; i < menu.size(); i++){
items.add(Menu.NONE, Menu.NONE, i, menu.getItem(i));
}
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
// update highlighted item in the navigation menu
menuItem.setChecked(true);
int position=items.getOrder();
return true;
}
});
UPDATE
You can get position using this trick
final List<MenuItem> items = new ArrayList<>();
Menu menu;
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);.
menu = navigationView.getMenu();
for(int i = 0; i < menu.size(); i++){
items.add(menu.getItem(i));
}
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
// update highlighted item in the navigation menu
menuItem.setChecked(true);
int position = items.indexOf(menuItem);
return true;
}
});
You can just take its order if you specify the "android:orderInCategory" attribute for menu items:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:orderInCategory="0"
android:title="#string/news" />
<item
android:orderInCategory="1"
android:title="#string/search" />
</menu>
val navigationView = findViewById<NavigationView>(R.id.navigation)
navigationView.setNavigationItemSelectedListener { menuItem ->
val menuItemOrder = menuItem.order
true
}
Or, use this in case you don't want to specify orders by hand:
val navigationView = findViewById<NavigationView>(R.id.navigation)
navigationView.setNavigationItemSelectedListener { menuItem ->
val menuItemIndex = bottomNavigation.menu.children.indexOf(menuItem)
true
}
If you are using menu_drawer.xml, you just have to add an id in the items like this:
<item
android:id="#+id/nav_top_stories"
android:title="#string/txt.menu.item1"
/>
With this you just have to test on menuItm.getId():
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
// update highlighted item in the navigation menu
menuItem.setChecked(true);
switch(menuItem.getId()){
case R.id.txt_menu_item1 : //do what you want to do;
break;
case R.id.txt_menu_item2 : // etc,
}
return true;
}
});
If you are using dynamic menu, just use this method to add an item to you navigation drawer:
NavigationView.getMenu().add(int groupId, int itemId, int order, CharSequence title)
And then test by the order:
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener(){
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
// update highlighted item in the navigation menu
menuItem.setChecked(true);
switch(menuItem.getOrder()){
case 0 : //do what you want to do;
break;
case 1 : // etc,
default : //do whatever you want ;
}
return true;
}
});
In my case, i use
first test whit this..
Log.d(TAG, navigationView.getMenu().getItem(0).isChecked());
Log.d(TAG, navigationView.getMenu().getItem(1).isChecked());
Log.d(TAG, navigationView.getMenu().getItem(2).isChecked());
next this...
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
if(navigationView.getMenu().getItem(0).isChecked()) {
cerrarSesion();
}else {
navigationView.getMenu().getItem(0).setChecked(true);
seleccionarItem(navigationView.getMenu().getItem(0));
}
}
return false;
}
The easy, and most clean (in my opinion) way:
private int getBottomNavigationItemPosition(#MenuRes int itemId) {
final Menu bottomNavigationMenu = mBottomNavigationView.getMenu();
final int menuItemCount = bottomNavigationMenu.size();
for (int i = 0; i < menuItemCount; i++) {
if (bottomNavigationMenu.getItem(i).getItemId() == itemId) return i;
}
return -1; // the item with itemId was not found in Menu
}

Categories

Resources