在BottomNavigationView中设置最初选择的项目索引/ ID

时间:2023-01-19 09:03:33

I've implemented new BottomNavigationView (com.android.support:design:25.0.0) and have no idea how to set selection index or MenuItem id (in my case, mid 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 anyway any help will be appreciated. Thanks!

我已经实现了新的BottomNavigationView(com.android.support:design:25.0.0)并且不知道如何设置选择索引或MenuItem id(在我的情况下,默认情况下应选择mid项)。我担心现在没有这种可能性,因为它太原始了,但无论如何,任何帮助都将受到赞赏。谢谢!

7 个解决方案

#1


21  

Set the selected menu item ID using setSelectedItemId:

使用setSelectedItemId设置所选菜单项ID:

bottomNavigationView.setSelectedItemId(R.id.item_id);

This method started being available from Android Support Library 25.3.0.

此方法已从Android支持库25.3.0开始提供。

#2


44  

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:

正如user5968678所述,自Android支持库v25.3.0以来添加了新方法:

bottomNavigationView.setSelectedItemId(R.id.item_id);

so use in instead :)

所以请改用:)

#3


11  

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.

其中menuItemIndex是所选元素的索引。

#4


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)

菜单项也可用于以编程方式选择当前活动的目的地。可以使用MenuItem#setChecked(true)来完成

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

作为Jan发布的替代方案,您还可以通过id找到该项目:

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

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

另外,我建议调用.callOnClick()而不是.performClick()。

#5


1  

Stop using Reflection! It is bad!

停止使用Reflection!这是坏的!

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:

好吧,虽然支持库没有让我们选择从BottomNavigationView中选择要在第一次显示时显示的项目,我们有两种可能:

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:

当执行setupBottomNavigationView()方法时?在Activity onCreate()方法中,看一下:

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

Simple and without extensive code.

简单而没有广泛的代码。

Hope it helps!

希望能帮助到你!

#6


1  

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

如果你正在使用监听器,比如android studio中的默认实现,试试这个:

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));

#7


-1  

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

您可以扩展BottomNavigationView并使用反射来调用私有方法。

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

}

#1


21  

Set the selected menu item ID using setSelectedItemId:

使用setSelectedItemId设置所选菜单项ID:

bottomNavigationView.setSelectedItemId(R.id.item_id);

This method started being available from Android Support Library 25.3.0.

此方法已从Android支持库25.3.0开始提供。

#2


44  

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:

正如user5968678所述,自Android支持库v25.3.0以来添加了新方法:

bottomNavigationView.setSelectedItemId(R.id.item_id);

so use in instead :)

所以请改用:)

#3


11  

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.

其中menuItemIndex是所选元素的索引。

#4


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)

菜单项也可用于以编程方式选择当前活动的目的地。可以使用MenuItem#setChecked(true)来完成

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

作为Jan发布的替代方案,您还可以通过id找到该项目:

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

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

另外,我建议调用.callOnClick()而不是.performClick()。

#5


1  

Stop using Reflection! It is bad!

停止使用Reflection!这是坏的!

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:

好吧,虽然支持库没有让我们选择从BottomNavigationView中选择要在第一次显示时显示的项目,我们有两种可能:

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:

当执行setupBottomNavigationView()方法时?在Activity onCreate()方法中,看一下:

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

Simple and without extensive code.

简单而没有广泛的代码。

Hope it helps!

希望能帮助到你!

#6


1  

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

如果你正在使用监听器,比如android studio中的默认实现,试试这个:

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));

#7


-1  

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

您可以扩展BottomNavigationView并使用反射来调用私有方法。

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

}