41

我已经实现了 BottomNavigationView并且不知道如何设置选择索引或MenuItemid(在我的情况下,应该默认选择中间项)。

恐怕目前还没有这种可能性,因为它太原始了,但无论如何,任何帮助都会受到赞赏。谢谢!

4

12 回答 12

68

使用 设置选定的菜单项 ID setSelectedItemId

bottomNavigationView.setSelectedItemId(R.id.item_id);

此方法从 Android 支持库 25.3.0 开始可用。

于 2017-04-07T12:45:21.223 回答
55

对我有用的唯一解决方案是:

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

只需执行点击就可以了。希望我们能在未来的版本中获得额外的方法/属性。

升级版:

正如user5968678 提到的,自 Android 支持库 v25.3.0 以来添加了一个新方法:

bottomNavigationView.setSelectedItemId(R.id.item_id);

所以改用这个:)

于 2016-10-25T15:38:21.077 回答
21

我认为这个解决方案比公认的答案稍微优雅一些​​:

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

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

于 2017-01-14T18:07:15.227 回答
9

以下是文档所说的:

菜单项还可用于以编程方式选择当前处于活动状态的目的地。可以使用MenuItem#setChecked(true)

除了 Jan 发布的内容之外,您还可以通过 id 找到该项目:

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

另外,一般来说,我可以推荐调用.callOnClick()而不是.performClick().

于 2017-03-08T14:03:07.877 回答
3

我相信根据这里的答案,在不同的背景下看待这个背景下的问题。根据评估,需要的是专注于特定BottomNavigationView项目的能力(肯定是在持有不同片段的新班级中)。

现在,您可以使用 BottomNavigationView OR Buttons 或任何可点击的东西来启动新的活动: -

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

然后 - 在我们的 New_Activity 中,我们接收到意图 -

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

然后我们遍历 page 变量以找到当前 BottomNavigationView 所反映的数字/索引,然后我们设置我们的焦点菜单项(假设您的 BottomNavigationView 具有用于显示的菜单项)

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

这就回答了上面的问题。通过调用上面的帖子数可以很好地处理 Fragment 开关的其余部分:

bottomNavigationView.setOnNavigationItemSelectedListener(navListener);

然后是这样的:

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

注意: 使用BottomNavigationViewContentFrameLayout非常经济,并且与使用ViewPagerTablayout之类的不同,它会将您的代码削减到 50% 以上

于 2018-12-12T19:09:41.443 回答
3

如果您正在使用监听器,例如 android studio 中的默认实现,请尝试以下操作:

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));
于 2018-03-05T14:47:46.603 回答
2

bottomnavigation.BottomNavigationView 中初始选定项目的 Kotlin 代码:

bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
于 2019-01-19T15:11:40.737 回答
1

停止使用反射!这是坏的!

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

首先,使用循环:

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

其次,没有循环但有一个类变量(因为逻辑是从内部类中完成的):

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;

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

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

简单且没有大量代码。

希望能帮助到你!

于 2016-10-29T04:01:10.850 回答
1

您可以通过添加一个虚拟菜单项作为分配给 BottomNavigationView 的菜单中的第一项并将该项目设置为不可见来实现此效果。然后在您的重新选择处理程序中,调用 setSelectedItem(dummy) 到虚拟项目。因此,可见菜单项将表现为“虚拟”切换。我花了更多的工作来解决这个问题。您必须这样做才能在重新选择完成后调用 setSelectItem:

@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
    anyView.post(new Runnable() {
        @Override
        public void run() {
            navigationView.setSelectedItemId(R.id.action_dummy);
        }
    }
});
于 2020-11-09T14:41:52.220 回答
0

在导航中设置初始页面 - Jetpack Navigation

在导航图中设置属性“startDestination”,值应该是给片段的id。

<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>
于 2021-08-29T17:40:17.390 回答
0

您可以扩展 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);
    }

}
于 2016-10-29T00:52:40.213 回答
0

实现BottomNavigationView.OnNavigationItemSelectedListener并设置selectedItemIdat 初始化。

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
于 2019-04-24T02:10:40.763 回答