Set initially selected item index/id in BottomNavigationView
O

12

49

I have implemented BottomNavigationView and have no idea how to set selection index or MenuItem id (in my case, middle item should be selected by default).

I'm afraid there's no such possibility for now as far as it's too raw yet, but anyways any help will be appreciated. Thanks!

Orthography answered 25/10, 2016 at 9:52 Comment(4)
Refer this link. androidgifts.com/…Pentacle
Yes I know about BottomBar but I can't believe support.design's one has no possibility to select items programmatically :) Maybe some hacky solutions...Orthography
Look at this answer. This is the best solution.Lodgings
Added more "elegant" answer, you might check that one out.Krystalkrystalle
E
75

Set the selected menu item ID using setSelectedItemId:

bottomNavigationView.setSelectedItemId(R.id.item_id);

This method started being available from Android Support Library 25.3.0.

Emmenagogue answered 7/4, 2017 at 12:45 Comment(1)
Or use the property access syntax on Kotlin: bottomNavigationView.selectedItemId = R.id.item_idNews
O
58

The only solution that worked for me is:

View view = bottomNavigationView.findViewById(R.id.menu_action_dashboard);
view.performClick();

Simply performing click does the trick. Hope we'll get extra methods/properties in future releases.

UPD:

As user5968678 mentioned, a new method was added since Android Support Library v25.3.0:

bottomNavigationView.setSelectedItemId(R.id.item_id);

so use this instead :)

Orthography answered 25/10, 2016 at 15:38 Comment(1)
Best solution yetArsenical
K
21

I think this solution my be slightly more elegant than accepted answer:

bottomNavigationView.getMenu().getItem(menuItemIndex).setChecked(true)

where menuItemIndex is index of the selected element.

Krystalkrystalle answered 14/1, 2017 at 18:7 Comment(3)
Does not work. If you have animation enabled on your bottomNavigationBar you can see that color have been changed on the item that is selected, but animation is still on the first item of menu. Not available for now in the android lib. IF YOU WANT TO MAKE IT WORK ANYWAY: ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0)).getChildAt(menuItemIndex).performClick(); OR EVEN BETTER: ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0)).findViewById(R.id.id_menu_action).performClick();Churchless
Can you post your code? I'm using latest BottomNavigationView from google support library (25.1.0) and when I change selected index like that the animation works without problems.Krystalkrystalle
this will only set the menu to active, but not to trigger the menu itself, which is what i'm looking forAhwaz
M
9

Here's what the documentation says about it:

Menu items can also be used for programmatically selecting which destination is currently active. It can be done using MenuItem#setChecked(true)

As an alternative to what Jan posted, you can also find the item by id:

Menu menu = findViewById(R.id.navigation).getMenu();
menu.findItem(R.id.navigation_home).setChecked(true);

Also, in general, I can recommend calling .callOnClick() instead of .performClick().

Markos answered 8/3, 2017 at 14:3 Comment(0)
M
3

If you're using listener, like default implementation in android studio, try this:

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));
Moolah answered 5/3, 2018 at 14:47 Comment(0)
G
3

I believe the question in this context is being viewed in different contexts basing on answers here. According to assessment, whats required is ability to focus on specific BottomNavigationView item (definitely in new class holding different fragments).

Now, you could have BottomNavigationView OR Buttons or Anything clickable to launch new activity on intent : - i.e

Intent intent = new Intent(getActivity(), New_Activity.class);
    intent.putExtra("EXTRA_PAGE, 1);
    startActivityForResult(intent, 30);

Then -in our New_Activity, we receive the intent-

Intent intent = getIntent(); int page = intent.getExtras().getInt("EXTRA_PAGE);

We then loop over the page variable to find the number/Index for which the current BottomNavigationView is reflecting , THEN we set our focus menu item (assuming your BottomNavigationView has Menu Item for its display)

     if(page == 1) {
         currentselect = new Pending();
            bottomNavigationView.getMenu().getItem(0).setChecked(true);
}

This answers the question above. The rest of Fragment switch is handled well by number of posts above by invoking :

bottomNavigationView.setOnNavigationItemSelectedListener(navListener);

Then something like :

   private BottomNavigationView.OnNavigationItemSelectedListener navListener =
        new BottomNavigationView.OnNavigationItemSelectedListener(){
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                Fragment selectedFrag = null;
                switch (item.getItemId()) {
                    case R.id.pending:
                        selectedFrag = new Pending();
                        break;
                    case R.id.onTransmit:
                        selectedFrag = new inTransmit();
                        break;
                    case R.id.complete:
                        selectedFrag = new Complete();
                        break;
                }

                getSupportFragmentManager().beginTransaction().replace(R.id.select_field, selectedFrag).commit();

                return true;
            }
        };

NOTE: Using BottomNavigationView and ContentFrameLayout is soo economical and will slash down your code to over 50 % unlike using likes of ViewPager and Tablayout

Gyrate answered 12/12, 2018 at 19:9 Comment(0)
C
2

Kotlin Code for initial selected item in bottomnavigation.BottomNavigationView :

bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
Caseose answered 19/1, 2019 at 15:11 Comment(0)
H
1

Stop using Reflection! It is bad!

Well, while the support library does not gives us the option to select the item from the BottomNavigationView to be displayed on the first time when it is visible, we have two possibilities:

First, using loop:

private void setupBottomNavigationView() {
    // Get the menu from our navigationBottomView.
    Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
    // Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
    bottomNavigationMenu.findItem(R.id.action_one).setChecked(false);
    // Check the wished first menu item to be shown to the user.
    bottomNavigationMenu.findItem(R.id.action_two).setChecked(true);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {

    Menu bottomNavigationMenu = bottomNavigationView.getMenu();
            for (int i = 0; i < bottomNavigationMenu.size(); i++) {
                if (item.getItemId() != bottomNavigationMenu.getItem(i).getItemId()) {
                    bottomNavigationMenu.getItem(i).setChecked(false);
                }
            }

            switch (item.getItemId()) {
                case R.id.action_one :
                    replaceFragment(new OneFragment());
                    break;
                case R.id.action_two :
                    replaceFragment(new TwoFragment());
                    break;
                case R.id.action_three :
                    replaceFragment(new ThreeFragment());
                    break;
            }
            return false;
        }
    });
}

Second, without loop but with a class variable (because the logic is done from within inner class) :

private void setupBottomNavigationView() {
    // Get the menu from our navigationBottomView.
    Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
    // Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
    bottomNavigationViewMenu.findItem(R.id.action_one).setChecked(false);
    // Check the wished first menu item to be shown to the user. Also store that menu item on a variable to control when a menu item must be unchecked.
    mActiveBottomNavigationViewMenuItem = bottomNavigationViewMenu.findItem(R.id.action_two).setChecked(true);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem selectedMenuItem) {
            switch (selectedMenuItem.getItemId()) {
                case R.id.action_one :
                    replaceFragment(new OneFragment());
                    break;
                case R.id.action_two :
                    replaceFragment(new TwoFragment());
                    break;
                case R.id.action_three :
                    replaceFragment(new ThreeFragment());
                    break;
            }

            if (selectedMenuItem != mActiveBottomNavigationViewMenuItem){
                mActiveBottomNavigationViewMenuItem.setChecked(false);
                mActiveBottomNavigationViewMenuItem = selectedMenuItem;
            }

            return false;
        }
    });
}

private MenuItem mActiveBottomNavigationViewMenuItem;

When the setupBottomNavigationView() method is executed? In Activity onCreate() method, take a look:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ...
    setupBottomNavigationView();
}

Simple and without extensive code.

Hope it helps!

Heiser answered 29/10, 2016 at 4:1 Comment(0)
A
1

Implement BottomNavigationView.OnNavigationItemSelectedListener and set the selectedItemId at initialisation.

this.bottomNavigationView.setOnNavigationItemSelectedListener {
    val targetFragment = when (menuItem.itemId) {
        R.id.action_home -> {
            HomeFragment()
        }
        R.id.action_post -> {
            PostFragment()
        }
        R.id.action_settings -> {
            SettingsFragment()
        }
        else -> null
    }
    targetFragment?.let {
        this.activity?.supportFragmentManager?.transaction {
            replace(R.id.containerLayout, it, it.javaClass.simpleName)
        }
    }
    true
}

this.bottomNavigationView.selectedItemId = R.id.action_home
Alidia answered 24/4, 2019 at 2:10 Comment(0)
P
1

You can achieve this effect by adding a dummy menu item as the first item in the menu you assign to BottomNavigationView and setting this item to be invisible. Then in your reselect handler, call setSelectedItem(dummy) to the dummy item. As a result, the visible menu items will behave as "virtual" toggles. Took me more work than it should have to figure this one out. You will have to do it like this in order that the setSelectItem be called after the reselect is complete:

@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
    anyView.post(new Runnable() {
        @Override
        public void run() {
            navigationView.setSelectedItemId(R.id.action_dummy);
        }
    }
});
Pauli answered 9/11, 2020 at 14:41 Comment(0)
C
0

You can extend BottomNavigationView and use reflection to invoke private methods.

public class SelectableBottomNavigationView extends BottomNavigationView {

    public SelectableBottomNavigationView(Context context) {
        super(context);
    }

    public SelectableBottomNavigationView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SelectableBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setSelected(int index) {
        try {
            BottomNavigationMenuView menuView = (BottomNavigationMenuView) getField(BottomNavigationView.class, "mMenuView");
            OnNavigationItemSelectedListener listener = (OnNavigationItemSelectedListener) getField(BottomNavigationView.class, "mListener");
            try {
                Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
                method.setAccessible(true);
                // activate item.
                method.invoke(menuView, index);
                if (listener != null) {
                    // trigger item select event.
                    listener.onNavigationItemSelected(getMenu().getItem(index));
                }
            } catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    private Object getField(Class clazz, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Field f = clazz.getDeclaredField(fieldName);
        f.setAccessible(true);
        return f.get(this);
    }

}
Chronon answered 29/10, 2016 at 0:52 Comment(1)
Reflection is a bad idea!Heiser
T
0

To set initial page in navigation - Jetpack Navigation

set property "startDestination" inside in the navigation graph, value should be the id given to the fragment.

<navigation
app:startDestination="@+id/navigation_movies"
...
>

<!--  default page -->
 <fragment
     android:id="@+id/navigation_movies"
     ...`enter code here`
 />
 <fragment
     android:id="@+id/navigation_tv_shows"
     ...
 />
</fragment>
Transudate answered 29/8, 2021 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.