如何在 BottomNavigationView 中设置所选项目
Posted
技术标签:
【中文标题】如何在 BottomNavigationView 中设置所选项目【英文标题】:How to Set selected item in 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 ComponentInfogym.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)
【问题讨论】:
伤心,没人知道为什么…… 【参考方案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然后找到菜单..它的工作代码......我试过这个 如何更改选中项的颜色? @AlanNelson 检查此***.com/a/40326245/7130121 请注意,这只会突出显示该项目,但不会单击它。【参考方案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_
android:layout_>
<android.support.design.widget.BottomNavigationView
android:background="@color/colorWhite"
android:id="@+id/gfPrlBnvBtmView"
android:layout_
android:layout_
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
注意:确保将
myNavigationViewId
和other_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_
android:layout_
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
有效。
【讨论】:
以上是关于如何在 BottomNavigationView 中设置所选项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在 BottomNavigationView 中动态隐藏菜单项?
如何禁用 BottomNavigationView 移位模式?
如何在 BottomNavigationView 中设置指标? [复制]
如何在没有 ActionBar 的 AndroidX 中设置 BottomNavigationView