Set selected item in Android BottomNavigationView

前端 未结 21 2313
谎友^
谎友^ 2020-11-27 14:16

I am using the new android.support.design.widget.BottomNavigationView from the support library. How can I set the current selection from code? I realized, that

相关标签:
21条回答
  • 2020-11-27 15:05
    private void setSelectedItem(int actionId) {
        Menu menu = viewBottom.getMenu();
        for (int i = 0, size = menu.size(); i < size; i++) {
            MenuItem menuItem = menu.getItem(i);
            ((MenuItemImpl) menuItem).setExclusiveCheckable(false);
            menuItem.setChecked(menuItem.getItemId() == actionId);
            ((MenuItemImpl) menuItem).setExclusiveCheckable(true);
        }
    }
    

    The only 'minus' of the solution is using MenuItemImpl, which is 'internal' to library (though public).

    0 讨论(0)
  • 2020-11-27 15:05

    IF YOU NEED TO DYNAMICALLY PASS FRAGMENT ARGUMENTS DO THIS

    There are plenty of (mostly repeated or outdated) answers here but none of them handles a very common need: dynamically passing different arguments to the Fragment loaded into a tab.

    You can't dynamically pass different arguments to the loaded Fragment by using setSelectedItemId(R.id.second_tab), which ends up calling the static OnNavigationItemSelectedListener. To overcome this limitation I've ended up doing this in my MainActivity that contains the tabs:

    fun loadArticleTab(articleId: String) {
        bottomNavigationView.menu.findItem(R.id.tab_article).isChecked = true // use setChecked() in Java
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.main_fragment_container, ArticleFragment.newInstance(articleId))
            .commit()
    }
    

    The ArticleFragment.newInstance() method is implemented as usual:

    private const val ARG_ARTICLE_ID = "ARG_ARTICLE_ID"
    
    class ArticleFragment : Fragment() {
    
        companion object {
            /**
             * @return An [ArticleFragment] that shows the article with the given ID.
             */
            fun newInstance(articleId: String): ArticleFragment {
                val args = Bundle()
                args.putString(ARG_ARTICLE_ID, day)
                val fragment = ArticleFragment()
                fragment.arguments = args
                return fragment
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-11-27 15:06

    I you don't want to modify your code. If so, I recommended you to try BottomNavigationViewEx。

    You just need replace call a method setCurrentItem(index); and getCurrentItem()

    Click here to view the image

    0 讨论(0)
  • 2020-11-27 15:08

    From API 25.3.0 it was introduced the method setSelectedItemId(int id) which lets you mark an item as selected as if it was tapped.

    From docs:

    Set the selected menu item ID. This behaves the same as tapping on an item.

    Code example:

    BottomNavigationView bottomNavigationView;
    bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView);
    bottomNavigationView.setOnNavigationItemSelectedListener(myNavigationItemListener);
    bottomNavigationView.setSelectedItemId(R.id.my_menu_item_id);
    

    IMPORTANT

    You MUST have already added all items to the menu (in case you do this programmatically) and set the Listener before calling setSelectedItemId(I believe you want the code in your listener to run when you call this method). If you call setSelectedItemId before adding the menu items and setting the listener nothing will happen.

    0 讨论(0)
  • 2020-11-27 15:08

    Add android:enabled="true" to BottomNavigationMenu Items.

    And then set bottomNavigationView.setOnNavigationItemSelectedListener(mListener) and set it as selected by doing bottomNavigationView.selectedItemId = R.id.your_menu_id

    0 讨论(0)
  • 2020-11-27 15:08

    This will probably be added in coming updates. But in the meantime, to accomplish this you can use reflection.

    Create a custom view extending from BottomNavigationView and access some of its fields.

    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 {
                Field f = BottomNavigationView.class.getDeclaredField("mMenuView");
                f.setAccessible(true);
                BottomNavigationMenuView menuView = (BottomNavigationMenuView) f.get(this);
    
                try {
                    Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
                    method.setAccessible(true);
                    method.invoke(menuView, index);
                } catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    And then use it in your xml layout file.

    <com.your.app.SelectableBottomNavigationView
            android:id="@+id/bottom_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:itemBackground="@color/primary"
            app:itemIconTint="@drawable/nav_item_color_state"
            app:itemTextColor="@drawable/nav_item_color_state"
            app:menu="@menu/bottom_navigation_menu"/>
    
    0 讨论(0)
提交回复
热议问题