如何在BottomNavigationView中设置选定项

38

我正在尝试在Activity创建时设置默认项,但它似乎没有生效?这是我的代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_userhome);
    mTextMessage = (TextView) findViewById(R.id.message);
    profile = (FrameLayout) findViewById(R.id.profile);
    mall = (FrameLayout) findViewById(R.id.mall);
    dietplan =(FrameLayout) findViewById(R.id.dietplan);
    BottomNavigationView navigation = (BottomNavigationView) 
    findViewById(R.id.navigation);
    navigation.setSelectedItemId(R.id.dietplan);
     navigation.setOnNavigationItemSelectedListener 
    (mOnNavigationItemSelectedListener);
}

但似乎 navigation.setSelectedItemId(R.id.dietplan); 不起作用。请帮我设置底部导航栏的默认项:

这是我的堆栈跟踪(logcat):

FATAL EXCEPTION: main
   Process: gym.android.ommsoftware.gym, PID: 1915
   java.lang.RuntimeException: Unable to start activity ComponentInfo{gym.android.ommsoftware.gym/gym.android.ommsoftware.gym.Userhome}: java.lang.NullPointerException
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2404)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2464)
       at android.app.ActivityThread.access$900(ActivityThread.java:172)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:146)
       at android.app.ActivityThread.main(ActivityThread.java:5653)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
       at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.NullPointerException
       at gym.android.ommsoftware.gym.Userhome.onCreate(Userhome.java:57)
       at android.app.Activity.performCreate(Activity.java:5541)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2368)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2464) 
       at android.app.ActivityThread.access$900(ActivityThread.java:172) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:146) 
       at android.app.ActivityThread.main(ActivityThread.java:5653) 
       at java.lang.reflect.Method.invokeNative(Native Method) 
       at java.lang.reflect.Method.invoke(Method.java:515) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) 
       at dalvik.system.NativeStart.main(Native Method) 

难过,没有人知道为什么... - user8389458
14个回答

62

不是选择,而是需要使用setChecked(true)来选中该项。尝试使用以下代码:

mBottomNavigationView=(BottomNavigationView)findViewById(R.id.bottom_nav);
mBottomNavigationView.getMenu().findItem(R.id.item_id).setChecked(true);

BottomNavigationView 中选中的项会被突出显示。


我之前尝试过这个 navigation.getMenu().findItem(R.id.dietplan).setChecked(true); 但是它会抛出 NullPointerException。 - Abhijeet
首先初始化 bottom_nav,然后找到菜单... 这是工作代码... 我已经尝试过了。 - Abhishek Singh
如何更改已选项目的颜色? - Alan Nelson
1
@AlanNelson 请查看此链接 https://dev59.com/clkS5IYBdhLWcg3wJDUP#40326245 - Abhishek Singh
4
请注意,这只是突出显示该项而不会点击它。 - 6rchid

23

我只是分享我的工作源代码

在XML中,

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.BottomNavigationView
        android:background="@color/colorWhite"
        android:id="@+id/gfPrlBnvBtmView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:layout_alignParentBottom="true"
        app:menu="@menu/bottom_navigation_main" />
</LinearLayout>

在Java中,

  public class TestActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener
{
    private BottomNavigationView mBtmView;
    private int mMenuId;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
        setContentView(R.layout.test);
        mBtmView = (BottomNavigationView) findViewById(R.id.gfPrlBnvBtmView);
        mBtmView.setOnNavigationItemSelectedListener(this);
        mBtmView.getMenu().findItem(R.id.action_yoga).setChecked(true);
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        // uncheck the other items.
        mMenuId = item.getItemId();
        for (int i = 0; i < mBtmView.getMenu().size(); i++) {
            MenuItem menuItem = mBtmView.getMenu().getItem(i);
            boolean isChecked = menuItem.getItemId() == item.getItemId();
            menuItem.setChecked(isChecked);
        }

        switch (item.getItemId()) {
            case R.id.action_food: {
            }
            break;
            case R.id.action_medical: {
            }
            break;
            case R.id.action_yoga: {
            }
            break;
            case R.id.action_postures: {
            }
            break;
        }
        return true;
    }
}

如果有人给我负面评价,请解释原因,然后我才会修改我的回答。谢谢。 - Magesh Pandian
4
你为什么要检查所有菜单?你可以这样做 item.setChecked(true); - sushildlh

12

Kotlin解决方案

在一个Fragment中

getActivity()?.myNavigationViewId?.selectedItemId = R.id.other_tab_id

在一个Activity中

myNavigationViewId?.selectedItemId = R.id.other_tab_id

注意:请确保将myNavigationViewIdother_tab_id替换为您实际的导航视图和选项卡ID。


9

提供信息:对于片段,onCreateView

BottomNavigationView mBottomNavigationView = getActivity().findViewById(R.id.bottomNavigationView);

mBottomNavigationView.setSelectedItemId(R.id.your_item);

2
谢谢你!我一直遇到NPE错误。因为我是在一个片段中执行findViewById(R.id.bottom_nav),所以我需要你的getActivity()来执行它。谢谢。 - Forrest

4

Kotlin扩展版本的Abshishek's答案:

internal fun BottomNavigationView.checkItem(actionId: Int) {
    menu.findItem(actionId)?.isChecked = true
}

// use 
bottom_navigation.checkItem(R.id.navigation_home)

这不会触发 OnNavigationItemSelectedListener


4

使用Fragment的Kotlin解决方案

var fragment = Fragment()
bottomNav = findViewById(R.id.bottom_nav)
bottomNav.setOnNavigationItemSelectedListener { item ->
  when (item.itemId) {
    R.id.home -> {
      fragment = HomeForm()
    }
    R.id.score -> {
      fragment = ScoreForm()
    }
  }
  supportFragmentManager
    .beginTransaction()
    .replace(R.id.frame_layout, fragment)
    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
    .commit()
  true
}
bottomNav.selectedItemId = R.id.score // init open score tab

2
您可以使用索引在BottomNavigationView中设置选择,如下所示:
public void selectBottomNavigationOption(int index) {
        switch (index) {
            case 0:
                index = R.id.action_1;
                break;
            case 1:
                index = R.id.action_2;
                break;
            case 2:
                index = R.id.action_3;
                break;
            case 3:
                index = R.id.action_4;
                break;
        }
        bottomNavigationView.setSelectedItemId(index);
    }

2

您可以使用:

    navigationView?.menu?.findItem(drawableMenuItem.id)?.isChecked = true

并且它不会触发OnNavigationItemSelectedListener事件。


1
这对我有效。

活动布局:

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottomNavigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemBackground="@color/colorPrimary"
        app:itemIconTint="@color/tabs"
        app:itemTextColor="@color/tabs"
        app:menu="@menu/bottom_navigation_main" />

color/tabs.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="@color/not_active" android:state_checked="false"/>
    <item android:color="@color/active" android:state_checked="true"/>

</selector>

点击回调函数:
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_tab0:
            setFragment(f0);
            break;
        case R.id.action_tab1:
            setFragment(f1);
            break;
    }
    return true; // not false!
}

1
android:enabled="true" 添加到您的 BottomNavigation 菜单项中。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:id="@+id/menu_id"
    android:enabled="true"
    android:icon="@drawable/ic_my_icon"
    android:title="@string/menu_title"/>
</menu>

onCreate()方法中,通过bottomNavigationView.setOnNavigationItemSelectedListener(mListener)设置监听器。
通过bottomNavigationView.selectedItemId = R.id.menu_id设置所需的选定项。
这将在活动创建时触发NavigationItemSelectedListener中的onNavigationItemSelected()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接