【问题标题】:How to Set selected item in BottomNavigationView如何在 BottomNavigationView 中设置所选项目
【发布时间】:2017-08-31 22:41:49
【问题描述】:

我正在尝试为创建的活动设置默认项目,但它不起作用? 这是我的代码:

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) 

【问题讨论】:

  • 伤心,没人知道为什么……

标签: android bottomnavigationview


【解决方案1】:

您需要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
  • 首先初始化bottom_nav然后找到菜单..它的工作代码......我试过这个
  • 如何更改选中项的颜色?
  • 请注意,这只会突出显示该项目,但不会单击它。
【解决方案2】:

只需分享我的工作源代码

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

【讨论】:

  • 如果有人投反对票,请解释为什么只有我改变我的答案,谢谢
  • 为什么要检查所有菜单?你可以这样做item.setChecked(true);
【解决方案3】:

Kotlin 解决方案

在一个片段中

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

在活动中

myNavigationViewId?.selectedItemId = R.id.other_tab_id

注意:确保将 myNavigationViewIdother_tab_id 替换为您的实际导航视图和标签 ID。

【讨论】:

    【解决方案4】:

    仅供参考:对于片段,onCreateView

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

    【讨论】:

    • 谢谢你!我一直在获得NPE。我需要你的getActivity() 来执行findViewById(R.id.bottom_nav),因为我是从片段中执行的。谢谢。
    【解决方案5】:

    Abshishek's 的 Kotlin 扩展版回答:

    internal fun BottomNavigationView.checkItem(actionId: Int) {
        menu.findItem(actionId)?.isChecked = true
    }
    
    // use 
    bottom_navigation.checkItem(R.id.navigation_home)
    

    这不会触发OnNavigationItemSelectedListener

    【讨论】:

      【解决方案6】:

      使用 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
      

      【讨论】:

        【解决方案7】:

        您还可以使用以下索引在 BottomNavigatioView 中设置选择:

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

        【讨论】:

          【解决方案8】:

          你可以使用:

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

          它不会触发OnNavigationItemSelectedListener 事件。

          【讨论】:

            【解决方案9】:

            这对我有用

            活动布局:

            <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" />
            

            颜色/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!
            }
            

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                如果您想要的是被点击的元素在视图中被忽略并且没有作为“选定”返回,您可以在处理点击后返回 false,在某些情况下和某些设计中,您可能需要打开一个活动而不是一个片段,这将在活动关闭后选择底部项目。

                private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
                    when (item.itemId) {
                        R.id.navigation_shipment -> {
                            currentItem = TAB_INDEX_SHIPMENT
                            val intent = Intent(this, BookShipmentActivity::class.java)
                            startActivity(intent)
                            return@OnNavigationItemSelectedListener false
                        }
                    }
                    false
                }
                

                【讨论】:

                  【解决方案12】:

                  有两个场景

                  设置选中的菜单项 ID。这与点击项目的行为相同。

                  代码示例:

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

                  我只需要检查它而不点击

                  代码示例:

                    BottomNavigationView bottomNavigationView= (getActivity()).findViewById(R.id.bottom_navigation);
                      bottomNavigationView.getMenu().findItem(R.id.action_manage_orders_id).setChecked(true);
                  

                  【讨论】:

                    【解决方案13】:

                    对我来说,setSelectedItemId(int id) 只显示了片段,但选择的菜单项仍然是错误的。

                    我发现在BottomNavigationView 全部设置完成后调用setSelectedItemId(int id) 是不够的。

                    我停止在onCreate(savedInstanceState: Bundle?) 中调用setSelectedItemId(int id),而是开始在onResume() 中调用它。这解决了问题。

                    【讨论】:

                      【解决方案14】:

                      如果您使用导航组件并想要所有控制,我应该如下所示。

                        private fun setupDashboard() {
                          binding.navBottomHome.setOnNavigationItemSelectedListener {
                              when (it.itemId) {
                                  R.id.dashboardFragment -> {
                                      findNavController(viewId = R.id.dashboardNavGraph).navigate(R.id.dashboardFragment)
                                      binding.navBottomHome.isSelected = true
                                  }
                                  R.id.ordersFragment -> {
                                      findNavController(viewId = R.id.dashboardNavGraph).navigate(R.id.ordersFragment)
                                      binding.navBottomHome.isSelected = true
                                  }
                                  R.id.productsFragment -> {
                                      findNavController(viewId = R.id.dashboardNavGraph).navigate(R.id.productsFragment)
                                      binding.navBottomHome.isSelected = true
                                  }
                                  else -> {
                                      findNavController(viewId = R.id.dashboardNavGraph).navigate(R.id.settingsFragment)
                                      binding.navBottomHome.isSelected = true
                                  }
                              }
                              Log.d("TAG++", "Item selected")
                              true
                          }
                      }
                      

                      简而言之,设置监听器并设置binding.navBottomHome.isSelected = true 有效。

                      【讨论】:

                        猜你喜欢
                        • 2017-03-05
                        • 2023-03-06
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多