Set initially selected item index/id in BottomNavigationView

邮差的信 提交于 2019-11-27 11:09:56

问题


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!


回答1:


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.




回答2:


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 have extra methods/properties in future releases.

UPD:

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

bottomNavigationView.setSelectedItemId(R.id.item_id);

so use in instead :)




回答3:


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.




回答4:


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().




回答5:


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));



回答6:


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




回答7:


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!




回答8:


Kotlin Code for initial selected item in bottomnavigation.BottomNavigationView :

bottom_navigation_view.selectedItemId = R.id.navigation_item_messages



回答9:


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);
    }

}



回答10:


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


来源:https://stackoverflow.com/questions/40236786/set-initially-selected-item-index-id-in-bottomnavigationview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!